TransactionScope是否可以与预先存在的连接一起使用? [英] Does TransactionScope work with pre-existing connections?
问题描述
我有这样的代码:
try
{
using (TransactionScope scope = new TransactionScope())
{
some_db_function();
for (i = 0; i < 10; i++)
{
some_other_db_function();
}
scope.Complete();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + " all done transactions will rollback");
}
并且在db函数内部会发生以下情况:
and inside the db functions something like this happens:
private void some_db_functions()
{
using (TransactionScope scope = new TransactionScope())
{
//some processing on db
scope.Complete();
}
}
假设是数据库事务中有任何问题,例如在函数中插入或更新错误;到目前为止,所有已完成的交易都会回滚.但这不是那样的.虽然它会引发异常,并且父函数中的 scope.Complete()
永远不会触发,但仍然不会回滚任何东西.
It is supposed to be that if there was any problem in the database transactions, like an error inserting or updating in the functions; all the transactions that had been done so far get rolled back. But it does not work like that; and although it throws an exception and the scope.Complete()
in the parent function never gets triggered, still nothing get rolled back.
问题出在哪里?
推荐答案
IIRC,在连接创建/打开时会自动加入环境事务中;如果您在交易范围内创建连接,那么一切都应该很好.但是:
IIRC, automatic enlisting into ambient transactions happens at connection creation/opening time; if you create the connection inside the scope of the transaction, all should be good. However:
它们都使用先前声明的相同连接
they are all using the same connection, declared previously
如果连接存在于事务之外,则不会征用.
if the connection exists outside of the transaction, it won't enlist.
最佳实践是仅在工作单元周围创建/打开连接,而不是永远(并且:让连接池完成其工作).如果您遵循该做法,则应该可以正常工作.所以:
Best practice is to create/open a connection only around a unit of work, not forever (and: let connection pooling do its job). If you follow that practice, it should work fine. So:
这行不通:
using(var conn = CreateAndOpenConnection()) {
// ...
using(var tran = new TransactionScope()) {
SomeOperations(conn);
tran.Complete();
}
// ...
}
在哪里-这应该起作用:
where-as this should work:
using(var tran = new TransactionScope()) {
// ...
using(var conn = CreateAndOpenConnection()) {
SomeOperations(conn);
}
tran.Complete();
// ...
}
这篇关于TransactionScope是否可以与预先存在的连接一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!