【问题标题】:Why Am I Getting Error Using TransactionScope?为什么我在使用 TransactionScope 时会出错?
【发布时间】:2021-03-04 12:21:34
【问题描述】:

大家!

我在使用 TransactionScope 时遇到问题。我希望我的网络方法是事务性的。如果发生任何异常,我希望回滚所有数据库更改。否则,提交。请参阅下面的错误消息。

System.ApplicationException:someClass :: Method public 中的错误 returnType methodName(parameterType 参数) :

System.ApplicationException: someClass :: Method private中的错误 字符串 someMethod() :

System.Data.Odbc.OdbcException (0x80131937):

错误 [08003] [Sybase][ODBC 驱动程序]连接未打开

在 System.Data.Odbc.OdbcConnection.Open_EnlistTransaction(事务 交易)

在 System.Data.Odbc.OdbcConnectionOpen.EnlistTransaction(Transaction 交易)

在 System.Data.Odbc.OdbcConnection.EnlistTransaction(事务 交易)

在 System.Data.Odbc.OdbcConnection.Open()

在 c:\somePath\someClass.cs:line 35 中的 someNameSpace.someMethod() 处

以下是我的代码的摘录。我做错了什么?

 [WebMethod]
 public returnType methodName(parameterType parameter)
 {
     using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
     {
         try
         {
             var someValue = someMethod();
                 :
                 :
                 :

             transactionScope.Complete();

             return response;
         }
         catch (Exception ex)
         {
             return ErrorMessages(ex);
         }
     }
 }

 private string someMethod()
 {
     var commandText = "...some valid SQL expression...";
     var commandType = CommandType.Text;

     try
     {
         using (var odbcConnection = new OdbcConnection(DefaultDbConnection.ToString()))
         {
             using (var odbcCommand = new OdbcCommand(commandText, odbcConnection))
             {
                 odbcConnection.Open();  // Exception is thrown here!
                 odbcCommand.CommandType = commandType;

                 using (var reader = odbcCommand.ExecuteReader())
                 {
                     reader.Read();
                     return reader.GetString(0);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         throw new ApplicationException("Error in someMethod.", ex);
     }
 }

提前感谢您的帮助!

【问题讨论】:

  • 大概你是说相同的代码在没有事务范围的情况下也能正常工作,对吗?最终:并非所有提供商都支持该 API,我建议无论如何反对它。你在这里谈什么? (使用 ODBC 很难知道这一点,因为这是一个备用的遗留 API)。请注意,您可以尝试将 Open() 调用移到命令构造之上。
  • 嗨,马克!...感谢您的及时回复。我很高兴我的问题引起了您的注意。我希望你能回应。我看过你的很多回复。我总是觉得它们很有帮助......
  • 当我注释掉 "using (var transactionScope = new TransactionScope())" 和 "transactionScope.Complete()" 行时,Web 方法可以完美运行,完全符合预期,没有错误或警告。只有当我引入 TransactionScope 时,当 odbcConnection 尝试登记事务时,“odbcConnection.Open()”才会引发以下异常: System.Data.Odbc.OdbcException (0x80131937): ERROR [08003] [Sybase][ODBC Driver]连接未打开
  • 我尝试了以下... using (var transactionScope = new TransactionScope()) using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) // 默认使用 (var transactionScope = new TransactionScope( TransactionScopeOption.RequiresNew)) 它们都不起作用。
  • 我在“使用 (var odbcCommand = new OdbcCommand(commandText, odbcConnection))”之前尝试过“odbcConnection.Open()”之前。那也没用。

标签: c# ado.net odbc transactionscope


【解决方案1】:

最终,并非所有连接类型(也不是所有平台)都支持基于事务范围的事务,即使它们支持:由于与多个系统通信时的范围问题,它们可能是不可预测的,需要 DTC 之类的东西。

相反,我强烈建议:不要使用事务范围(除非你有充分的理由)。相反,更喜欢更简单且支持更广泛的 ADO.NET 事务模型:

  • 在连接上使用BeginTransaction(或异步等效项)以(不出所料)开始事务
  • 在代码中携带该事务实例
  • 在每个命令上设置事务属性(我一直不明白为什么有必要这样做,因为它是通过连接隐含的,但是:确实如此)
  • 确保在最后提交或中止事务,最好使用try/catch/finally,这样它在成功和失败中都能正确发生

【讨论】:

  • 根据您之前的回复,我决定放弃 TransactionScope 并以“老式”方式进行...使用BeginTransactiontry/catch/finally ......实际上你在上面写的。我真的很感谢您的帮助...谢谢!
猜你喜欢
  • 2010-10-18
  • 2021-10-02
  • 1970-01-01
  • 2022-01-21
  • 2021-09-10
  • 2019-01-14
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多