与Oracle程序的事务处理

oymdgrw7  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(156)

在调用事务中的存储过程后,我尝试回滚事务,但数据库中的所有更改仍然处于活动状态。
代码:

using (DbContext context = new DbContext("name=data"))
      {
      try
        {
             using (DbContextTransaction transaction = context.Database.BeginTransaction())
                    {

                var mID = _id ?
                     new ObjectParameter("mID", _id) :
                     new ObjectParameter("mID", typeof(int));
    
                ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("MY_PROCEDURE", mID,);
                       
               // some condition of with ret.Value
              transaction.Rollback();

过程没有自己的事务。DB自动提交已关闭。
我使用的是.NET Framework 4.5.0版。(如果不是TransactionScope)
使用using和try块进行的更改不会更改行为。
我也尝试了isolationLevel,但没有变化。

r7s23pms

r7s23pms1#

如果存储过程MY_PROCEDURE在过程的末尾包含一个COMMIT语句,那么当你尝试ROLLBACK事务时,它将ROLLBACK到最后一个COMMIT,并且因为你在过程中显式地告诉它COMMIT,那么ROLLBACK将不会有后续的更改。
如果是这种情况,您的代码按设计工作,但设计不符合您的意图;要修复它,您需要从过程中删除COMMIT语句,然后当您ROLLBACK事务时,它将ROLLBACK到事务的开始。

  • (注意:在每个req语句之前和之后,req语句将隐式地COMMIT;如果您的过程运行并包含SQL语句,那么您将永远不能将事务ROLLBACK到这些语句之前。)*

一般来说,你不应该在过程中使用COMMIT语句,因为它会阻止你在过程之外控制事务(正如你所发现的那样),并且意味着你不能在同一个事务中调用多个过程,如果后面的一个失败,你就不能选择ROLLBACK所有的过程。

  • (注意:这种情况的例外是自治事务,您(几乎)总是希望在过程中执行COMMIT,因为它们在事务会话之外执行,因此会话的正常事务控制不会影响它们的行为。

相关问题