我可以通过尝试在同一个连接中打开 2 个连接来成功重现此问题(即使第一个连接在打开下一个连接之前已关闭),如下所示:
TransactionScope
实际上,我正在尝试利用
var connectionString = "some connection";
using (var t = new TransactionScope())
{
using (var con1 = new OracleConnection(connectionString))
{
con1.Open();
}
using (var con2 = new OracleConnection(connectionString))
{
con2.Open();//exception thrown at here
}
}
为我的存储库实现某种
TransactionScope
(每个存储库都使用一个相同的连接字符串打开自己的连接)。上面的代码已尽可能简化,以帮助重现异常。我不太确定我是否做错了什么,或者至少在
Ambient transaction
中不支持
TransactionScope
。
我的项目面向 .NET Standard 2.0 (lib) 和 .NET Core (app) 2.2,OracleManagedDataAccess
是通过 nuget 安装的(当然是针对 .NET Standard)并且版本为 .NET Standard
。这是上面发布的异常的堆栈跟踪:
在 OracleInternal.MTS.MTSRMManager.CCPEnlistDistributedTxnToSysTxn(OracleConnectionImpl connImpl,事务 txn,MTSTxnRM txnRM,MTSTxnBranch txnBranch)
在OracleInternal.MTS.MTSRMManager.CCPEnlistTransaction(OracleConnectionImpl connImpl,事务事务,MTSTxnRM txnRM,MTSTxnBranch txnBranch)
在 OracleInternal.ConnectionPool.PoolManager`3.GetEnlisted(ConnectionString csWithDiffOrNewPwd,布尔值 bGetForApp,OracleConnection connRefForCriteria)在 OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securePassword, SecureString secureProxyPassword, OracleConnection connRefForCriteria)在 Oracle.ManagedDataAccess.Client.OracleConnection.Open()
。如果我不能使用
我有一种感觉,这是一个非常棘手的问题,几乎取决于OracleManagedDataAccess
2.19.3
,就没有简单的方法来实现
OracleManagedDataAccess
。TransactionScope 内的单个连接应该按预期工作。 当您登记到
从版本 2.1 开始,.NET Core 中的 System.Transactions 实现不包括对分布式事务的支持,因此您无法使用 TransactionScope 或 CommittableTransaction 跨多个资源管理器协调事务。
(来自有关 EF Core使用事务不支持分布式事务的理由是它们依赖于的 Microsoft Docs 文章)。
MSDTC,这是特定于Windows的。它与 .NET Core 作为跨平台框架的路线图不太相符。
编辑:另一种方法一般来说,应该格外谨慎地做出依赖分布式事务的决定,因为这些事务很容易成为可扩展性瓶颈。在现代架构中,通常不鼓励分布式事务。
在您的情况下,由于您的所有资源都是到同一数据库的连接,因此您实际上不需要分布式事务。我建议实施(环境)例如,您的应用程序中的每个逻辑/业务操作可能有一个工作单元实例。工作单元的实例将缓冲对数据库的所有请求的修改(使用您自己的数据结构来表示修改)。在操作结束时,将提交工作单元。提交操作将包括:
使用单个数据库连接执行所有缓冲修改
我设法通过抑制是否存在现有交易并且仍然存在来解决 设置 TransactionScopeAsyncFlowOption.Enabled 并且它工作完美
TransactionScope