TransactionScope - 基础提供程序在EnlistTransaction上失败.MSDTC被中止

m.e*_*son 14 c# msdtc entity-framework transactionscope oracle10g

我们的团队遇到的问题表现为:

基础提供程序在EnlistTransaction上失败; 无法访问已处置的对象.对象名称:'Transaction'.

在此输入图像描述

一旦我们开始使用TransactionScope来处理我们的应用程序的事务,它似乎就出现了.

堆栈跟踪的顶部部分被捕获为:

在System.Data.EntityClient.EntityConnection.EnlistTransaction(事务事务)处于System.Data.Objects.ObjectContext.EnsureConnection(),位于Reconciliation.Models的System.Data.Objects.ObjectContext.ExecuteStoreCommand(String commandText,Object [] parameters).在EntityDbEnvironment.cs中的Reconciliation.Models.Legacy.EntityDbEnvironment.ExecuteOracleSql(String sql)中的BillLines.BillLines.Reconciliation.Interfaces.IBillLineEntities.ExecuteStoreCommand(String,Object []):第41行

同时更新MSDTC日志,我已使用此处说明进行了提取:

pid=7060       ;tid=7908       ;time=04/29/2013-16:38:30.269   ;seq=136        ;eventid=TRANSACTION_BEGUN                        ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"transaction has begun, description :'<NULL>'"
pid=7060       ;tid=7908       ;time=04/29/2013-16:38:30.269   ;seq=137        ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"resource manager #1002 enlisted as transaction enlistment #1. RM guid = 'defc4277-47a6-4cd9-b092-93a668e2097b'"
pid=7060       ;tid=7908       ;time=04/29/2013-16:38:31.658   ;seq=138        ;eventid=RECEIVED_ABORT_REQUEST_FROM_BEGINNER     ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"received request to abort the transaction from beginner"
pid=7060       ;tid=7908       ;time=04/29/2013-16:38:31.658   ;seq=139        ;eventid=TRANSACTION_ABORTING                     ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"transaction is aborting"
pid=7060       ;tid=7908       ;time=04/29/2013-16:38:31.658   ;seq=140        ;eventid=RM_ISSUED_ABORT                          ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"abort request issued to resource manager #1002 for transaction enlistment #1"
pid=7060       ;tid=7908       ;time=04/29/2013-16:38:31.658   ;seq=141        ;eventid=RM_ACKNOWLEDGED_ABORT                    ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"received acknowledgement of abort request from the resource manager #1002 for transaction enlistment #1"
pid=7060       ;tid=7908       ;time=04/29/2013-16:38:31.658   ;seq=142        ;eventid=TRANSACTION_ABORTED                      ;tx_guid=60f6390c-7570-488a-97a9-2c3912c4ca3e     ;"TM Identifier='(null)                                            '" ;"transaction has been aborted"
Run Code Online (Sandbox Code Playgroud)

正如您在RM_ENLISTED_IN_TRANSACTION被记录后的第二天看到RECEIVED_ABORT_REQUEST_FROM_BEGINNER 一样.

我们无法理解这个中止请求的来源,或者为什么要提出这个请求.导致问题的SQL是一个简单的SELECT,我们可以通过数据库客户端无问题地执行.

该应用程序大部分时间都在工作,只是偶尔会显示此问题.

我们正在使用Oracle 10.2.0.5.0和Entity Framework.

UPDATE

根据@Astrotrain的建议,我在System.Transactions上设置了日志记录.产生的最终条目实际上是中途切断:

....
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Information">
<TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/TransactionScopeCreated</TraceIdentifier>
<Description>TransactionScope Created</Description>
<AppDomain>BillLineGeneratorUI.exe</AppDomain>
<ExtendedData xmlns="http://schemas.microsoft.com/2004/03/Transactions/TransactionScopeCreatedTraceRecord">
<TraceSource>[Base]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,异常实际上阻​​止了日志的完成.我能从中学到什么?有任何想法吗?

Ast*_*ain 7

我没有使用MSDTC跟踪工具(我发现可怕的斯巴达),我建议使用System.Transactions跟踪源 - 只需在web.config中包含以下内容:
如果您打开日志文件,SvcTraceViewer.exe您将获得一个很好的视觉效果表示步骤.

<configuration>
  <system.diagnostics>
   <trace autoflush="true" />
   <sources>
     <source name="System.Transactions" switchValue="Information">
       <listeners>
         <add name="tx"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData="C:\MyApp-transactions-log.svclog" />
       </listeners>
     </source>
   </sources>
  </system.diagnostics>
</configuration>
Run Code Online (Sandbox Code Playgroud)

本身不是解决方案,但这可能会为您提供有关出错的更多信息.


Ger*_*ard 1

我们也遇到了这个问题。解决它的最好方法似乎是打开一个新的数据库连接并只执行事务中所需的操作。保持交易量尽可能小总是好的。

 DatabaseContext db1 = new DatabaseContext();

 doSomeDatabaseActions(db1);

 TransactionOptions transOpts = new TransactionOptions();
 transOpts.IsolationLevel = System.Transactions.IsolationLevel.Serializable;

 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transOpts))
 {
     using (DatabaseContext db2 = new DatabaseContext())
     {
        doDatabaseChecksWithLock(db2);
        doChanges(db2);
        db2.SaveChanges();
     }

     scope.Complete();
  }
Run Code Online (Sandbox Code Playgroud)

我们在没有引入第二个连接的情况下遇到了问题。请注意,如果事务扩大(使 doSomeDatabaseActions 成为事务的一部分),则使用 1 个连接 (db1) 也会消除该错误。