问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何在数据库中用好Transaction

发布网友 发布时间:2022-04-07 19:41

我来回答

2个回答

懂视网 时间:2022-04-08 00:02

  • bool createB = false;  
  • bool createC = false;  
  •   
  • try  
  • {  
  •     //这里的操作是创建3个目录  
  •     Directory.CreateDirectory("\A");  
  •     createA = true;  
  •     Directory.CreateDirectory("\B");  
  •     createB = true;  
  •     Directory.CreateDirectory("\C");  
  •     createC = true;  
  • }  
  • catch (System.Exception ex)  
  • {  
  •     //这里在捕捉到异常时,根据运行的结果进行回滚  
  •     if (createB)  
  •     {  
  •         Directory.Delete("\B");  
  •         Directory.Delete("\A");  
  •     }  
  •     if (!createB && createA)  
  •     {  
  •         Directory.Delete("\A");  
  •     }  
  • }  


  •  

    但是这里我们是把这3个操作当成一个整体来回滚,及时是简单的创建删除文件夹,我们可以看到catch中的回滚逻辑已经很复杂了。可以想象,如果A,B,C这3步不仅仅是创建目录,还有一些其他的操作,那么回滚的逻辑就非常复杂,此时,我们可以考虑把这一个分成几个小事务,分开回滚。代码可以这样写,这里我们使用了Framework提供的Transactin以及TransactioScope类。

     

    [csharp] view plaincopy技术分享技术分享  
    1. class Program  
    2.     {  
    3.         static void Main(string[] args)  
    4.         {  
    5.             //这里就不需要了try catch,因为scope就已经完成了这个功能,  
    6.             //即当有异常发生向外抛的时候,会尝试跳出这个using代码块,  
    7.             //CLR会在向代码块外边跑异常之前,分别取调用每个transaction的  
    8.             //roolback方法,只要rollback中你定义的逻辑没有问题,那么所有  
    9.             //的已发生的操作就会安全的回滚。  
    10.             using (var scope = new TransactionScope())  
    11.             {  
    12.                 var A = new OperationA();  
    13.                 Transaction.Current.EnlistVolatile(A, EnlistmentOptions.None);  
    14.                 A.DoWork();  
    15.   
    16.                 OperationB B = new OperationB();  
    17.                 Transaction.Current.EnlistVolatile(B, EnlistmentOptions.None);  
    18.                 B.DoWork();  
    19.                 scope.Complete();  
    20.             }  
    21.         }  
    22.   
    23.   
    24.     }  
    25. }  
    26.   
    27. class OperationA : IEnlistmentNotification  
    28. {  
    29.     private bool _isCommitSucceed = false;  
    30.   
    31.     public void Commit(Enlistment enlistment)  
    32.     {  
    33.         enlistment.Done();  
    34.     }  
    35.   
    36.     public void DoWork()//这是自定义的方法,不是继承IEnlistmentNotification  
    37.     {  
    38.         Directory.CreateDirectory("\A");  
    39.         //这里还有一些其他的关于A的复杂操作  
    40.         _isCommitSucceed = true;  
    41.     }  
    42.   
    43.     public void InDoubt(Enlistment enlistment)  
    44.     {  
    45.         enlistment.Done();  
    46.     }  
    47.     public void Prepare(PreparingEnlistment preparingEnlistment)  
    48.     {  
    49.         preparingEnlistment.Prepared();  
    50.     }  
    51.     public void Rollback(Enlistment enlistment)  
    52.     {  
    53.         //这里回滚A的一些操作,当然这里的操作逻辑需要你自己来写。  
    54.         //比如说查看是否创建成功,或者有一些其他的信号标记,通过这些  
    55.         //标记你来决定是删除目录还是其他的什么回滚操作。  
    56.         if (_isCommitSucceed)  
    57.             Directory.Delete("\A");  
    58.         enlistment.Done();  
    59.     }  
    60. }  
    61.   
    62. class OperationB : IEnlistmentNotification  
    63. {  
    64.     private bool _isCommitSucceed = false;  
    65.   
    66.     public void Commit(Enlistment enlistment)  
    67.     {  
    68.         enlistment.Done();  
    69.     }  
    70.   
    71.     public void DoWork()  
    72.     {  
    73.         //这里是关于B的一些复杂操作  
    74.         throw new Exception("test");  
    75.         //这里依然有一些操作代码,但是我们模拟的是B操作途中抛出异常,所以这里的代码不会执行  
    76.     }  
    77.   
    78.     public void InDoubt(Enlistment enlistment)  
    79.     {  
    80.         enlistment.Done();  
    81.     }  
    82.     public void Prepare(PreparingEnlistment preparingEnlistment)  
    83.     {  
    84.         preparingEnlistment.Prepared();  
    85.     }  
    86.     public void Rollback(Enlistment enlistment)  
    87.     {  
    88.         if (_isCommitSucceed)  
    89.         {  
    90.             //这里回滚B的一些已经存在的操作。  
    91.         }  
    92.         enlistment.Done();  
    93.     }  


    这里的机制是这样的,可能是scope.Complete()方法中有某种特别的操作,去告诉CLR这次所有的操作都顺利完成了,在跳出这个scope的时候就不用调用那些transaction的rollback方法了。如果没有执行到scope.Complete()方法,那么就会在跳出这个scope代码块的时候调用rollback方法。一般造成这个的原因是在某个transaction的逻辑操作中出现异常,造成从此次直接抛出异常跳出这个代码块,没有机会执行下边的代码。可以看出这里的重点也是写rollback的逻辑,但是相对于原来的catch中的逻辑,这里分开为多个小的逻辑,相对来说容易了很多。

    这只是个人写的一种使用回滚的逻辑。在使用IEnlistmentNotification的时候,也有人把业务逻辑写入到Commit中。如果想真正理解transaction回滚的机制,建议深入理解一下TransactionScope与Transactiond的实现机制。

    关于使用Transaction对于非数据库事务的操作

    标签:

    热心网友 时间:2022-04-07 21:10


    ASP
    的实际操作中,总会发生这样的情况,如在银行,从我的帐户往费文华的帐户
    划款,
    我的帐户显示已经划出,
    但因银行的系统出现故障,
    导致费文华帐户的数据库更
    改失败,这应该怎样处理呢?我帐户的金额应该没有损失吧?

    你的利益当然没有损失,已经更改的帐户数据库资料会自动恢复。

    这里用到的就是互动功能(
    TRANSACTION

    ,它是由
    IIS

    MTS

    Mircrosoft
    Transaction Server
    )共同完成的。它的功能就是:当
    ASP
    程序中所有的数据库的更改都
    成功时,
    才算成功;
    如果其中有一个数据库更改失败,
    则其它业已更改的数据库记录都
    将自动恢复。

    SQL SERVER

    ORACLE
    数据库都提供了互动功能,但
    ACCESS
    没有提供。

    这种互动功能作用于一个
    ASP
    程序的范围,就是说,凡是涉及到这个程序的所有
    的数据库都有互动功能。方法是在
    ASP
    程序的第一行加上:

    TRANSACTION=Required
    以告诉
    IIS
    本程序要使用互动的功能,具体
    ASP
    程序:

    < %@ TRANSACTION=Required LANGUAGE="VBScript"% >
    ……

    < % Set obj1 = Server.CreateObject("testobj.cls1")% >
    < % = obj1.data3t(1,10)% >
    < %
    Sub OnTransactionCommit()
    ……

    End Sub
    Sub OnTransactionAbort()
    ……

    End Sub
    % >
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    ...频数和频率成正比,2频数一定时,频率与总次数成反比,对不对_百度... ...总次数之间的关系是( ) A.频数越大,频率越大 B.总次数一定时,频数越... 实验的总次数、频数及频率三者的关系是( )A.频数越大,频率越大B.频数... 嘎牙鱼的做法大全 安无线网要用多少元网费要交多少元不用用了要不要交网费,想寻求大家的... 无线网费1年多少钱 "Hbr"作为“港”的缩写,其在英语中的使用频率和应用示例如何? 【车主点评:吉利汽车帝豪GL 使我荣华富贵】 请问,如果,家用,自动挡,帝豪gl,英朗,科沃兹,卡罗拉,轩逸,同等价位,建议... ...景点?既能休闲的时候看看又能长点知识@@谢谢各位了! 描写对人热情的成语 描写蒙古族同胞热情好客的成语 急求!!我需要《蓝猫龙骑团》的所有成员的资料 夸人好客的成语 殷勤好客成语的意思是什么? 银行卡能透支消费,但是能透支支取吗? 什么好客的成语 手机qq邮箱4.0显示此邮件无其他应用支持打开是什么意思 建设银行卡可以透支吗?业务需要怎么办理? 关于热情好客的成语 我的农业银行卡可以透支吗 形容热情好客的人们的成语 农业银行储蓄卡可以透支吗? 描写热情好客的词语 关于好客的成语有哪些? 描写“热情好客”的词语有哪些? 中国银行的银行卡能透支吗?如果能,能透支多少? 饿了么在移动O2O应用React Native的技术实践 饿了么在移动O2O应用React Native的技术实践 形容一个人热情好客可以用哪些成语来夸他们? “好客”的近义词是什么? 如何解决黑眼圈 热情好客的名言3条 描写主人热情好客的成语 形容蒙古族人民热情好客的成语 晚上熬夜熬的久了,眼圈发黑,如何用中医的方法改善? 把被子叠成天鹅,求解 将十进制数100转换为等价的八进制数要求写出计算过程 【信息】十进制100转换为八进制、十六进制。 十进制的100等于八进制的多少 十进制数100转换为八进制数为提问 水管价格多少钱?家装使用水管 钉钉在线课堂无回放名单导出失败 十进制数100转换成八进制数为 A 144 B 644 C 164 D FF4? 3号弹窗什么意思 十进制数如何转八进制.讲的越详细越好 十进制100转为八进制不应该是124吗,为什么正确答案是144 北京健康宝出现该用户为14天内新办卡的用户 换厨房所有水管贵不贵,大约多少钱。 家装饮用水用铜管,人工费大约多少钱一米?