在将OracleConnection与TransactionScope一起使用时具有这种奇怪的行为。
如果我尝试在事务作用域中使用connection.BeginTransaction(),则会得到简单优雅的InvalidOperationException:连接已经是本地或分布式事务的一部分。
这是一些代码:
var trxOptions = new TransactionOptions();
trxOptions.IsolationLevel = IsolationLevel.ReadCommitted;
using (var transaction = new TransactionScope(TransactionScopeOption.Required,trxOptions))
{
var c = ConfigurationManager.ConnectionStrings["oracle_test"].ConnectionString;
using (var oracle = new OracleConnection(c))
{
oracle.Open();
using (var tr = oracle.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
var cmd = oracle.CreateCommand();
cmd.CommandText = "INSERT INTO simple_user VALUES('a')";
cmd.ExecuteNonQuery();
tr.Commit();
}
}
// now go to sql server and insert data
transaction.Complete();
}
如果我不使用BeginTransaction,一切正常。有什么想法可以使它起作用吗?
PS:我在Sql Server上没有这样的问题。
编辑
感谢您的回答,我想我应该添加一些编辑以使我的问题更清楚。
首先,我上面提供的代码是问题的演示。可以说我有两个dll的MyProject.Oracle.dll和MyProject2.MsSql.dll,我想在这些dll中使用方法,并且它们使用db.BeginTransaction()。如果这些dll使用过TransactionScope,那么我的外部事务就不会有问题。被分配的交易将得到处理,而不会出现任何问题。但是我无法更改dll中的代码。
为什么db.BeginTransaction()适用于SqlServer但不适用于Oracle?
最佳答案
我和NHibernate一起遇到了同样的问题。
其他答案表明不要混合使用TransactionScope和BeginTransaction。不幸的是,没有任何来源支持这一说法。这是我的研究:
如MSDN(搜索“mix”)和in this discussion所述,即使是对于SQL Server,也不应混用这两个概念。我仍然不清楚为什么它对于本地和分布式事务都适用于SQL Server。
有些人似乎认为这是一个愚蠢的问题,但是在NHibernate的上下文中看到它是有道理的(请参阅here,here和here)。
关于c# - 事务作用域因Oracle : Connection is already part of a local or a distributed transaction中的BeginTransaction而失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6870901/