c# - 环境事务中的 TransactionScope 错误不会回滚事务

标签 c# asp.net transactions informix transactionscope

我使用这样的环境事务:


using(TransactionScope tran = new TransactionScope()) {
    CallAMethod1();//INSERT
    CallAMethod2();//INSERT
    tran.Complete();
}

CallAMethod2(); 方法返回受影响的行 =-264 因此它无法插入,但是第一个插入已提交!

我想知道如何使用 ambient transaction 以及如果第二种方法有多个需要内部事务的操作,我应该将这些操作放在内部事务中吗? 像这样:

     DAL_Helper.Begin_Transaction();

              //------Fill newKeysDictioanry

                affectedRow = DBUtilities.InsertEntityWithTrans("table2", newKeysDictioanry, DAL_Helper);

                if (affectedRow == 1)
                {
                    if (!string.IsNullOrEmpty(sp_confirm))
                    {
                        result_dt = UserTransactionDAL.Run_PostConfirm_SP(sp_PostConfirm, OBJ.ValuesKey, DAL_Helper);
                        if (result_dt.Rows.Count > 0 && result_dt.Rows[0][0].ToString() == "0")
                        {
                            DAL_Helper.current_trans.Commit();

                            if (DAL_Helper.connectionState == ConnectionState.Open)
                            {
                                DAL_Helper.Close_Connection();
                            }
                            return 1;// affectedRow;
                        }
                        else
                        {
                            DAL_Helper.current_trans.Rollback();
                            if (DAL_Helper.connectionState == ConnectionState.Open)
                            {
                                DAL_Helper.Close_Connection();
                            }
                            return -2; 
                        }
                    }
//etc

最佳答案

1) 您需要检查 tran.Complete(); 是否被调用。如果 tran.Complete(); 被调用,TransactionScope 被认为成功完成。

来自 MSDN

When your application completes all work it wants to perform in a transaction, you should call the Complete method only once to inform that transaction manager that it is acceptable to commit the transaction. Failing to call this method aborts the transaction.

调用tran.Complete();是为了通知交易管理器完成交易。实际上,事务管理器不会跟踪您的 Db 适配器,也不知道连接中的操作是成功还是失败。您的应用程序必须通过调用 Complete 告知它

How does TransactionScope roll back transactions?

要使您的交易失败,只需确保您没有在代码中调用 tran.Complete();:

If no exception occurs within the transaction scope (that is, between the initialization of the TransactionScope object and the calling of its Dispose method), then the transaction in which the scope participates is allowed to proceed. If an exception does occur within the transaction scope, the transaction in which it participates will be rolled back.

在您的情况下,如果您认为操作失败,您可以在 CallAMethod2(); 中抛出异常,因此 tran.Complete(); 是 < strong>不调用,事务被回滚。

2) 您可以检查的第二件事是您的连接是否在事务中登记。如果未登记连接,TransactionScope 不会回滚。可能出现的问题是:

在这些情况下,您可以尝试手动注册您的连接(从上面的链接中提取):

connection.EnlistTransaction(Transaction.Current)

关于你的第二个问题:

what if the second method has more than one action which need internal transaction , should i put these actions in internal transaction ?

我想说这实际上取决于您是否将 CallAMethod2(); 视为自动 操作,这意味着您可以在别处直接调用它而无需将其包装在事务中.大多数情况下,创建内部事务是有意义的,因为事务可以嵌套。对于您的情况,建议在您的 CallAMethod2(); 中也使用 TransactionScope,我们在创建新事务范围时有一些选项:

The TransactionScope class provides several overloaded constructors that accept an enumeration of the type TransactionScopeOption, which defines the transactional behavior of the scope. A TransactionScope object has three options:

Join the ambient transaction, or create a new one if one does not exist.

Be a new root scope, that is, start a new transaction and have that transaction be the new ambient transaction inside its own scope.

Not take part in a transaction at all. There is no ambient transaction as a result.

选择哪一个取决于您的应用。就您而言,我想您可以选择第一个选项。以下是来自 MSDN 的示例

void RootMethod()
{
     using(TransactionScope scope = new TransactionScope())
     {
          /* Perform transactional work here */
          SomeMethod();
          scope.Complete();
     }
}

void SomeMethod()
{
     using(TransactionScope scope = new TransactionScope())
     {
          /* Perform transactional work here */
          scope.Complete();
     }
}

关于c# - 环境事务中的 TransactionScope 错误不会回滚事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28191333/

相关文章:

c# - 使用 EF 的 MVC 3 图像

c# - 如果第一次没有找到任何内容,如何正确地多次查询数据库以获取某个值 C#

javascript - 在 ASP.NET MVC 中使用 TypeScript

time - Spanner 的只读事务

c# - c#中的组合框选择值

c# - 使用 UITableViewDataSource 在 MonoTouch 中填充一个简单的 UITableView - 如何使用 UITableViewDataSource

c# - 当没有要求和的内容时,Linq .Sum() 函数失败

c# - 从 JQuery 添加 asp.net 自定义用户控件

java - Spring 事务管理 : Cannot resolve reference to bean 'transactionManager'

java - 使用 Wicket + Spring + Hibernate 的三层分层应用程序。你将如何处理交易?