为啥我在使用 TransactionScope 时会出错?
Posted
技术标签:
【中文标题】为啥我在使用 TransactionScope 时会出错?【英文标题】: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()”之前。那也没用。 【参考方案1】:最终,并非所有连接类型(也不是所有平台)都支持基于事务范围的事务,即使它们支持:由于与多个系统通信时的范围问题,它们可能是不可预测的,需要 DTC 之类的东西。
相反,我强烈建议:不要使用事务范围(除非你有充分的理由)。相反,更喜欢更简单且支持更广泛的 ADO.NET 事务模型:
在连接上使用BeginTransaction
(或异步等效项)以(不出所料)开始事务
在代码中携带该事务实例
在每个命令上设置事务属性(我一直不明白为什么有必要这样做,因为它是通过连接隐含的,但是:确实如此)
确保在最后提交或中止事务,最好使用try
/catch
/finally
,这样它在成功和失败中都能正确发生
【讨论】:
根据您之前的回复,我决定放弃 TransactionScope 并以“老式”方式进行...使用BeginTransaction
和try
/catch
/finally
......实际上你在上面写的。我真的很感谢您的帮助...谢谢!以上是关于为啥我在使用 TransactionScope 时会出错?的主要内容,如果未能解决你的问题,请参考以下文章
错误 - 具有多个数据库连接的 LINQ/TransactionScope
在 .NET Core/.NET 5+ 中使用 TransactionScope 和 SQL 连接池时如何避免 PlatformNotSupportedException