Saga 完成导致分布式事务完成错误

发布于 2025-01-01 07:06:43 字数 2794 浏览 1 评论 0原文

处理顺序:

  • Saga 消息处理程序接收包含数据项的第一条消息。
  • 消息处理程序使用具有自己的数据库事务的业务对象。
  • 如果项目更新正常,则数据库事务提交并且 saga 完成。
  • Saga 消息处理程序接收包含数据项的第二条消息。
  • 消息处理程序在尝试打开新的数据库事务时抛出异常,如上所述。

错误消息:

System.Data.SqlClient.SqlException (0x80131904): Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.

堆栈跟踪:

2012-01-27 14:07:47,407 [Worker.9] ERROR 

LawCover.LISServices.LISBankAgent.SagaMessageHandler [(null)] - Exception details
System.Data.SqlClient.SqlException (0x80131904): Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName)
   at System.Data.SqlClient.SqlConnection.BeginTransaction(IsolationLevel iso, String transactionName)
   at System.Data.SqlClient.SqlConnection.BeginTransaction()
   at LawCover.LIS.DataAccess.ConnectionManager.BeginTransaction()
   at LawCover.LISServices.LISBankAgent.LISMethods.AddCreditCardPaymentSettlementScheduleItemsAndReceiptsIntoLISForCurrentMessages(BankResponseFileProcessed message) in C:\Projects\LIS Improvements\LIS\Source\LISServices\LISBankAgent\LISMethods.cs:line 53
   at LawCover.LISServices.LISBankAgent.SagaMessageHandler.Handle(BankResponseFileProcessed message) in C:\Projects\LIS Improvements\LIS\Source\LISServices\LISBankAgent\SagaMessageHandler.cs:line 177

有相当多的代码涵盖了上述流程,但我很高兴发布有用的代码。

Process order:

  • Saga message handler receives first message containing data items.
  • Message handler uses business objects that has it's own database transaction.
  • If items are updated OK, database transaction commits and saga completes.
  • Saga message handler receives second message containing data items.
  • Message handler throws exception trying to open new database transaction as above.

Error message:

System.Data.SqlClient.SqlException (0x80131904): Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.

Stack Trace:

2012-01-27 14:07:47,407 [Worker.9] ERROR 

LawCover.LISServices.LISBankAgent.SagaMessageHandler [(null)] - Exception details
System.Data.SqlClient.SqlException (0x80131904): Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
   at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName)
   at System.Data.SqlClient.SqlConnection.BeginTransaction(IsolationLevel iso, String transactionName)
   at System.Data.SqlClient.SqlConnection.BeginTransaction()
   at LawCover.LIS.DataAccess.ConnectionManager.BeginTransaction()
   at LawCover.LISServices.LISBankAgent.LISMethods.AddCreditCardPaymentSettlementScheduleItemsAndReceiptsIntoLISForCurrentMessages(BankResponseFileProcessed message) in C:\Projects\LIS Improvements\LIS\Source\LISServices\LISBankAgent\LISMethods.cs:line 53
   at LawCover.LISServices.LISBankAgent.SagaMessageHandler.Handle(BankResponseFileProcessed message) in C:\Projects\LIS Improvements\LIS\Source\LISServices\LISBankAgent\SagaMessageHandler.cs:line 177

There's quite a lot of code covering the above flow but I'm happy to post what will be useful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里寻她 2025-01-08 07:06:43

我剥离了事务,发现 saga 处理程序正在打开另一个数据库连接,并且默认情况下,该连接已登记在 DTC 中。我在连接字符串中添加了“Enlist=false”,因为需要捕获数据库抛出的异常并进行相应处理,而不是破坏分布式事务。现在它的行为符合预期。

感谢您的意见,我将重新审视代码并采纳您的意见。

I peeled back the transactions to find that the saga handler was opening another database connection and by default, the connection is enlisted in the DTC. I added "Enlist=false" to the connection string as the exceptions thrown by database need to be caught and dealt accordingly rather than collapsing the distributed transaction. Now it behaves as expected.

Thanks for your input, I'll be revisiting the code and taking your comments on-board.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文