灰鸽子

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
using(TransactionScope scope1 = new TransactionScope()) 
//Default is Required 
{ 
     using(TransactionScope scope2 = new 
      TransactionScope(TransactionScopeOption.Required)) 
     {
     ...
     } 

     using(TransactionScope scope3 = new TransactionScope(TransactionScopeOption.RequiresNew)) 
     {
     ...
     } 

     using(TransactionScope scope4 = new 
        TransactionScope(TransactionScopeOption.Suppress)) 
    {
     ...
    } 
}

首先来看官方给出的解释

使用 Required 创建了一个新范围 (scope1)。范围 scope1 是根范围,因为它创建了一个新事务(事务 A),并使事务 A 成为环境事务。Scope1 后来又创建了三个对象,并用不同的 TransactionScopeOption 值对其中每个对象进行了实例化。例如,scope2 是用 Required 创建的;由于存在环境事务,因此该范围联接 scope1 所创建的第一个事务。请注意,scope3 是新事务的根范围,而 scope4 则没有环境事务。

 

再看试验结果:

public string test(string str)
        {
            try
            {
                using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { Timeout = new TimeSpan(0, 5, 0), IsolationLevel = IsolationLevel.ReadUncommitted }))
                {
                    Document_ASN_Header header = new Document_ASN_Header();
                    header.AddDate = DateTime.Now;
                    header.AddWho = 1;
                    header.OwnerID = 118;
                    header.DocumentType = 8;
                    header.DocumentStatus = 15;
                    header.DocumentNo = str;
                    db.Document_ASN_Header.InsertOnSubmit(header);
                    db.SubmitChanges();
                    Document_ASN_Details details = new Document_ASN_Details();
                    details.CustomField1 = "!@#$%^&&*()";
                    details.AddDate = DateTime.Now;
                    details.AddWho = 1;
                    details.DocumentASNNo = str;
                    details.SKUNO = "20100018";//20100018
                    try
                    {
                        DateTime dt = DateTime.Parse("2012*02-01");
                    }
                    catch (Exception e)
                    {

                        insertLogError(new EDI_Log_Result()
                        {
                            RETMSG = e.Message
                        });
                        return e.Message;
                    }
                    db.Document_ASN_Details.InsertOnSubmit(details);
                    insertLogOk(new EDI_Log_Result()
                    {
                        RETMSG = "OK"
                    });
                    db.SubmitChanges();
                    ts.Complete();
                    return "ok";

                }
            }
            catch(Exception e)
            {
                insertLogError(new EDI_Log_Result()
                {
                    RETMSG = e.Message
                });
                return e.Message;
            }
        }
         
        private void insertLogError(EDI_Log_Result log)
        {
            HongTuDataContext logDB = new HongTuDataContext();
            using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.Suppress, new TransactionOptions() { Timeout = new TimeSpan(0, 5, 0), IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                logDB.EDI_Log_Result.InsertOnSubmit(log);
                logDB.SubmitChanges();
                ts2.Complete();
            }
        }
        
        private void insertLogOk(EDI_Log_Result log)
        {
            using (TransactionScope ts3 = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { Timeout = new TimeSpan(0, 5, 0), IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                db.EDI_Log_Result.InsertOnSubmit(log);
                db.SubmitChanges();
                ts3.Complete();
            }
        }

大致的意思是往数据库中插入一个Header和Details信息

如果SKUNO为空会导致SqlException

DateTime的转换是一个验证基础数据的条件的一个模拟

把日志记录分成了两个方法

Error是记录错误日志时所使用的方法,不相同的数据源链接

Ok是记录正确日志所使用的方法,相同的数据链接

记录DateTime转换错误

使用Error方法(不相同的数据源链接)

TransactionScopeOption参数为Suppress与RequiresNew时能够保存成功,返回该字符串未被识别为有效的 DateTime。

TransactionScopeOption参数为Required时建立分布式事务(在能建立分布式事务的前提条件下),结果未知,预测不能保存

 

个人理解:

因为采用不同的数据链接,而且参数为Suppress与RequiresNew,所以与ts事务是无关和同等地位的状态,所以类似独立事务,能够保存

建立分布式事务,Required环境事务是ts但是,在此ts并没有显示提交,所以不能保存数据

使用Ok方法(相同的数据链接)

Required:无法保存数据库,返回该字符串未被识别为有效的 DateTime。
RequiresNew:无法保存数据库,返回连接当前已登记事务。请完成当前事务,然后重试。
Suppress:无法保存数据库,返回该字符串未被识别为有效的 DateTime。

 

个人理解:

Required环境事务是ts但是,在此ts并没有显示提交,所以不能保存数据

Suppress虽然无环境事务,但是是统一数据连接,应当也是相同的事务ts但是,在此ts并没有显示提交,所以不能保存数据

RequiresNew就如提示所示,当前链接已经有未提交事务存在,所以不能提交新事务

记录正确日志

使用Error方法(不相同的数据源链接)

Required:建立分布式事务(在能建立分布式事务的前提条件下),结果未知,预测能够保存
RequiresNew:可以保存数据库
Suppress:可以保存数据库

 

个人理解:

因为采用不同的数据链接,而且参数为Suppress与RequiresNew,所以与ts事务是无关和同等地位的状态,所以类似独立事务,能够保存

建立分布式事务,Required环境事务是ts但是,在此ts有显示提交,所以可以保存数据

使用Ok方法(相同的数据链接)

Suppress:可以保存数据库
RequiresNew:连接当前已登记事务。请完成当前事务,然后重试。
Required:可以保存数据库

 

个人理解:

Required环境事务是ts且ts有显示提交,所以可以保存数据

Suppress虽然无环境事务,但是是统一数据连接,应当也是相同的事务ts且在此ts有显示提交,所以可以保存数据

RequiresNew就如提示所示,当前链接已经有未提交事务存在,所以不能提交新事务

 

最外层catch因为不存在事务嵌套,所以使用不同的数据连接时,都可以成功,但是使用相同的数据连接,提交会出错因为相同的数据链接,相同事务,错误数据也会一同提交,所以会在记录日志时产生异常,导致不能记录日志。

 

欢迎各位童鞋讨论,个人愚见哈!

 

posted on 2012-05-23 19:49  zxl359592450  阅读(5967)  评论(1编辑  收藏  举报