c# - 在嵌套事务范围内打开两个 SQL 连接时挂起事务
问题描述
我试图了解下面的代码有什么问题:
using (var scope1 = new TransactionScope())
{
var connection1 = new SqlConnection("...");
connection1.Open();
using (var scope2 = new TransactionScope())
{
SqlConnection connection2 = new SqlConnection("...");
connection2.Open();
connection2.Close();
scope2.Complete();
}
connection1.Close();
scope1.Complete();
}
应用程序非常复杂,因此存在TransactionScope
. 在上面的代码中,当一个连接打开时,在 SQL Server 中创建了事务,所以实际上创建了两个事务,因为连接被打开了两次。
我通过调用以下 SQL 语句检查了这一点:
SELECT * FROM sys.sysprocesses WHERE open_tran = 1
当 scope1 中的环境事务完成时,数据库中还有一个事务。connection2.Close() 创建的事务仍然挂起。我的问题是为什么这个交易仍然存在以及如何更正代码。
编辑:
我想使用在外部定义的一个 SQL 连接TransactionScope
可能是一个答案,但也许存在更好的东西?
解决方案
该代码将需要分布式事务,因为您同时打开了两个单独的 SqlConnection 对象。如果在启动第二个 TransactionScope 之前关闭 SqlConnection,则初始连接和事务将被重用,您将不需要 DTC 事务。
无论如何,我认为这是进行 DTC 交易的无害副作用,其跟踪方式略有不同。查看
select st.session_id, is_local, is_enlisted, at.transaction_state
from sys.dm_tran_session_transactions st
join sys.dm_tran_active_transactions at
on at.transaction_id = st.transaction_id
对我来说,为打开的第二个会话(spid 65)输出一行,并指示事务已提交。
session_id is_local is_enlisted transaction_state
----------- -------- ----------- -----------------
65 0 1 6
transaction_state=6 表示事务已提交。https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-active-transactions-transact-sql?view=sql-server-2017
推荐阅读
- graphdb - 在没有用户可以访问我的存储库的情况下,如何仅使用 Visual Graph 选项卡来可视化我的本体?
- c# - 从 C# 在 Azure Bash 中执行命令
- swift - 如何自动调整 NSTextField 的高度?
- python - Tensorflow,预期 conv2d_input 有 4 个维度
- powershell - 如何确定文件或目录是否正在使用?
- kotlin - 如何在 Quarkus 中注册 Jackson 模块?
- javascript - HTML Web 组件中的客户端元素大小调整问题
- android - 为什么新创建的 Android Camera2 MP4 文件无法在某些播放器上播放,而在其他播放器上则无法播放
- typescript - 使用嵌套泛型接口仅允许数组中的某些类型
- c - 我已经为 spoj 问题“The Next Palindrome”编写了一个代码,并且在我的提交中得到了错误的答案信息