大家好我们已经开始使用事务范围了,下面是代码片段。我们需要了解的是,在每次使用连接后,我们的底线是否会处理/关闭特定连接?所以,自关闭以来,transaction.complete如何运作?
using (TransactionScope transScope = new TransactionScope())
{
try
{
string myConnStringLocal = "User Id=***;Password=****;Host=" + globalSettings.settingLocalIP + ";Database=" + globalSettings.settingLocalDB;
using (MySqlConnection connectionLocal = new MySqlConnection(myConnStringLocal))
{
try{
connectionLocal.Open();
}
Catch(Exception e)
{
}
finally{
connectionLocal.Close();
}
}
string myConnStringCentral = "User Id=***;Password=*****;Host=" + globalSettings.settingCentralIP + ";Database=" + globalSettings.settingCentralDB;
using (MySqlConnection connectionCentral = new MySqlConnection(myConnStringCentral))
{
try{
connectionCentral.Open();
}
Catch(Exception e)
{
}
finally{
connectionCentral.Close();
}
}
string myConnStringCentralCopy = "User Id=*****;Password=*****;Host=" + globalSettings.settingCentralCopyIP + ";Database=" + globalSettings.settingCentralCopyDB;
using (MySqlConnection connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy))
{
try{
connectionCentralCopy.Open();
}
Catch(Exception e)
{
}
finally{
connectionCentralCopy.Close();
}
}
transScope.Complete();
Console.WriteLine("Transaction is completed");
}
catch (Exception)
{
Console.WriteLine("Transaction is rolled back");
}
}
答案 0 :(得分:6)
TransactionScope.Complete
告诉所有交易经理他们可以提交此交易。并不能保证一切都会真正提交。调用 完成 方法后,所有事务管理器都会单独启动提交,如果所有事务管理器都成功,则认为事务已成功完成。
您可以参考此link for further details
答案 1 :(得分:4)
当您连接到单个TransactionScope
中的多个数据库时,该交易将升级为distributed
交易,并由MSDTC
使用2-phase commit进行协调。
关于连接关闭 - 这是在TransactionScope
内部关闭连接时的特殊情况,在内部由System.Transactions
基础架构管理,因此即使连接从您的端关闭,数据库会话仍可能仍处于打开状态。
请参阅MSDN上的说明:
如果启用了连接池,则在重置连接时会自动回滚使用Transact-SQL或BeginTransaction的挂起事务。如果关闭连接池,则在调用SqlConnection.Close后回滚事务。通过System.Transactions启动的事务是通过System.Transactions基础结构控制的,不受SqlConnection.Close的影响
编辑根据您的评论,您可以执行以下操作:
try
{
using (TransactionScope transScope = new TransactionScope())
{
string myConnStringLocal = ...;
using (var connectionLocal = new MySqlConnection(myConnStringLocal))
{
connectionLocal.Open();
// do your DB update
} //no need to close connection explicitly, the using() {..} statement does that for you
string myConnStringCentral = ...;
using (var connectionCentral = new MySqlConnection(myConnStringCentral))
{
connectionCentral.Open();
// do your DB update
} //no need to close connection explicitly, the using() {..} statement does that for you
string myConnStringCentralCopy = ...;
using (var connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy))
{
connectionCentralCopy.Open();
// do your DB update
} //no need to close connection explicitly, the using() {..} statement does that for you
transScope.Complete();
Console.WriteLine("Transaction is completed");
} //no need to dispose transactionScope explicitly, the using() {..} statement does that for you
}
catch (Exception)
{
// If any exception occurs in the try block above transScope.Complete() line will be caught here
// and will automatically cause the transaction to rollback.
Console.WriteLine("Transaction is rolled back");
}
// You can then start new TransactionScope if you want to further update more than one DB in a transactional manner.
try
{
using (TransactionScope transScope = new TransactionScope())
{
//...
}
}
catch (Exception)
{
//...
}
答案 2 :(得分:2)
调用Complete
方法时,如果没有抛出Exception
,则会提交范围内的所有内容。如果代码超出范围而没有Complete
,则不会发生任何提交。简而言之,如果您调用Complete
方法,那么,如果没有抛出Exceptions
,则将提交给定TransactionScope
范围内的事务。
另外,我必须补充说,可能还有一个层次结构,TransactionScopes
的树。您还可以设置TransactionScope
的行为,以便TransactionScope
的子范围回滚。