TransactionScope是否可以与预先存在的连接一起使用? [英] Does TransactionScope work with pre-existing connections?

查看:56
本文介绍了TransactionScope是否可以与预先存在的连接一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆