C# TransactionScope是否隐式应用,直到显式完成?
考虑以下方法C# TransactionScope是否隐式应用,直到显式完成?,c#,.net,transactionscope,C#,.net,Transactionscope,考虑以下方法 DoA() { using (TransactionScope scope = new TransactionScope) { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); SqlCommand command = new SqlCommand(query, connection); c
DoA()
{
using (TransactionScope scope = new TransactionScope)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
DoB();
scope.Complete();
}
}
}
DoB()
{
using (TransactionScope scope = new TransactionScope)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
DoC();
scope.Complete();
}
}
}
DoC()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
}
}
如果调用DoA()
,则DoB()
和DoC()
中的后续交互是否在DoA()
的事务上下文中运行,因为它与SQL Server有关?DoC()是否在DoA()
和DoB()
的事务上下文中运行
(还是我严重误解了什么?根据安迪的评论编辑: SQL server上似乎会发生类似的情况:
BEGIN TRANSACTION A
-- do A's work
-- B does NOT create a new transaction
-- do B's work
-- do C's work
COMMIT TRANSACTION A
如果在DoB()
中使用newtransactionscope(TransactionScopeOption.RequiresNew)
,则会发生以下情况
逻辑上所有代码都将是一个事务。嵌套的作用域不一定创建新事务(除非使用RequiresNew),因此它将是单个事务。现在,每个作用域都必须投票完成事务,因此在第二个作用域中,如果删除
complete
,应该会导致整个事务回滚
单据也将成为交易的一部分;环境事务将检测新连接并自动登记
请阅读解释在环境事务中注册行为的所有详细信息以及不同选项Requires
、RequiresNew
和Suppress
还要注意,如果您的连接没有使用完全相同的连接字符串,这将自动将整个事务升级为分布式事务。需要注意的是。您会得到嵌套事务:)有一些选项可以控制这一点。请参阅注释的“使用TransactionScopeOption管理事务流”进一步说明有关嵌套事务的备注必须使用相同的隔离级别才能参与环境事务。@DaveShaw我很难完全理解这一点,因为它与我在其他语言中的事务管理实践有很大的不同。说
DoC()
的工作在DoB()
的事务块中运行是否准确?(这反过来又嵌套在DoA()的事务中。)@svidgen啊,我明白了,我对DbTransactions不太熟悉,但这里的答案似乎可以解决这个问题:不会发生这种情况;它将是单个事务,因为B中使用的范围将加入现有的环境事务。如果B不投票支持完成
整个事务将回滚。@Andy感谢您的澄清。如果改用新建TransactionScope(TransactionScopeOptions.RequiresNew)
会发生这种情况吗?+1好信息。在我接受之前,您能否确认DoC()
是在DoA()
和/或DoB()
的环境事务中执行的?(这正是我所期望和想到的——但我想确定。)@svidgen更新了我的答案。
BEGIN TRANSACTION A
-- do A's work
BEING TRANSACTION B
-- do B's work
-- do C's work
COMMIT TRANSACTION B
COMMIT TRANSACTION A