c# – TransactionScope和Oracle的问题

我们编写了一个C#3.5客户端,使用ODP.NET与Oracle数据库(11g)进行通信.此应用程序具有批处理过程,其中执行长时间运行的任务,在TransactionScope中对数据库进行各种调用.在我们的开发环境中一切顺利,但在我们的一个客...

我们编写了一个C#3.5客户端,使用ODP.NET与Oracle数据库(11g)进行通信.

此应用程序具有批处理过程,其中执行长时间运行的任务,在TransactionScope中对数据库进行各种调用.

在我们的开发环境中一切顺利,但在我们的一个客户(拥有大量数据)的UAT环境中,出现两个交替(有时是一个,有时是另一个……)错误:

>无法登记分布式事务
>交易已中止. (内部异常:事务超时)

我们目前使用一天的超时时间进行交易(用于测试目的).

在UAT环境中运行所述进程导致在大约一段时间后停止. 10分钟,上面有一个例外,所以没有办法接近超时值.

这是第二个错误的堆栈跟踪片段:

at System.Transactions.TransactionStatePromotedAborted.CreateAbortingClone(InternalTransaction tx)
   at System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking)
   at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)
   at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent)
   at System.Transactions.TransactionScope.PushScope()
   at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption)
   at System.Transactions.TransactionScope..ctor()
   at Application.Domain.DataAccess.Oracle.EntityDaoBase`2.SaveItem(TEntity item, EntityReference`1 user)

该过程尝试将项目保存到事务范围内的数据库,但堆栈跟踪显示构造函数被命中为TransactionScope类,这意味着它创建了一个新的TransactionScope.

我到目前为止对吗?

因为我不太了解TransactionScope的内部工作原理,但是当你在范围内调用方法时,它会创建一个新的事务(假设继承自环境事务).

可能是因为我是对的,这个新事务没有继承正确的超时(但是默认的超时),所以嵌套事务会导致这个超时异常?

如果没有,任何想法可能是什么?另外,在环境事务中调用的方法中没有定义嵌套事务.

任何帮助将不胜感激!

编辑1:

该功能的简化代码片段:

public void SomeLengthyBatchProcess()
{
   using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
   {
       foreach (var item in Items)
       {
          SaveItemToDB(item);
       }

       transaction.Complete();
   }
}

public void SaveItemToDB(object item)
{
   using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
   {
       // Performing data persistency here

       transaction.Complete();
   }
}

编辑2:

好的,事实证明,方法’SaveItemToDB’中存在一个嵌套事务.经过一些同事挖掘代码后,我看到它定义了自己的TransactionScope,但没有选项和超时.

在修改此方法以使其具有与超时相同的参数后,我在客户的服务器上再次运行代码并且仍然没有运气(再次事务中止错误,超时).

所以我现在的问题如下:

>是否有必要为嵌套事务定义超时值,还是从环境事务中继承它?
>如果超时设置(可能除了我不知道的内部工作方式)与所有事务范围相同并且超时值定义为1天(如果发生异常,则可能发生超时异常)大约过了10分钟?
>是否可以阻止Oracle为连接字符串相同的事务创建分布式事务?
>分布式事务的额外开销是否会导致事务中止的异常?

我更新了代码段,以便更好地反映情况.

(顺便说一句:第二个嵌套事务是必要的,因为DAL也会单独保留一些子项,如果存在的话,整个项目当然应该在存在子项时出现问题时回滚)

希望通过这个添加,可以更容易地阐明这个问题!

解决方法:

由于我们找不到解决方案,因此我们决定停止将TransactionScope用于我们的目的并自行安排回滚.

我发现TransactionScope和Oracle混合不好,也许SQL Server可以更好地处理它,但这对我们来说不是一个选择.

谢谢阅读.

本文标题为:c# – TransactionScope和Oracle的问题

基础教程推荐