C# TransactionScope和Oracle的问题
我们已经编写了一个C#3.5客户机,它使用ODP.NET与Oracle数据库(11g)通信 此应用程序有一个批处理过程,其中执行长时间运行的任务,在TransactionScope中对数据库进行各种调用 在我们的开发环境中一切进展顺利,但在我们的一个客户(拥有大量数据)的UAT环境中,出现两个交替的错误(有时一个,有时另一个…):C# TransactionScope和Oracle的问题,c#,oracle,transactionscope,C#,Oracle,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)
进程尝试将一个项保存到事务范围内的DB中,但stacktrace显示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,但没有选项和超时
在修改此方法以使其具有相同的超时参数后,我在客户的服务器上再次运行了代码,但仍然没有成功(再次出现超时时事务中止错误)
因此,我现在的问题如下:
希望有了这一点,它将更容易阐明这个问题 您是否可以显示一段代码?从您提到的内容中,我唯一能找到的是与System.Transactions相关的内容。讨论非常激烈。当然,他们的“解决方案”是确保您至少使用ODP.NET 11.1.0.6.20或更高版本 因为找不到解决方案,我们决定停止使用TransactionScope,自己安排回滚 我发现TransactionScope和Oracle不能很好地混合,也许SQL Server处理得更好,但这不是我们的选择
感谢阅读。machine.config中的默认事务超时是10分钟……这可能就是您超时的原因
我知道这是一个老问题,但我会补充一点,因为我已经看到了很多 你在用RAC吗?您是否与DBA合作,查看是否遇到锁定/阻塞。我已经使用System.Transactions与Oracle进行了多年,我唯一一次遇到类似问题是在使用RAC时,需要进行额外的配置 发生的情况如下:您启动一个事务,并在事务期间打开连接(这很好)。但是,oracle服务未配置为用于分布式事务处理(这是服务上的一个简单复选框选项)。因此,其他连接开始跨越RAC集群中的多个实例,并且相关事务彼此不知道,从而导致.net进程自身阻塞
这是一个简单的解决方案。您正在使用的oracle服务只需要启用DTP 虽然这是一个老问题,但我希望这个答案能有所帮助。。。
对于长时间运行的事务,这种情况尤其发生,因为基础IDbConnection在更长的时间内不会保持打开状态,并且会为transactionscope的某些部分创建新连接(连接池)。出于同样的原因,如果返回并使用相同的打开连接,则长事务可能会成功,否则它将失败。唯一的解决方案是控制连接创建并确保整个过程中只使用一个连接。首先解决主要问题: