无法理解TransactionScope

时间:2012-09-19 21:21:28

标签: c# sql transactions

给出以下代码结构

func1()
{
    using (TransactionScope1)
    using (connection1)
    {
        "insert into table A"

        func2()

        "select from table B"
    }
}

func2()
{
    using (TransactionScope2)
    using (connection2)
    {
        foreach (x in y)
        {
            "select from table A"
            "insert into table B"
        }
    }
}

如果TransactionScope2已回滚,则"select from table B"将失败并显示The operation is not valid for the state of the transaction。据我所知,TransactionScope2正在加入第一个并将它们两个卷起来。 所以我更改了它以使用TransactionScopeOption.RequiresNew创建它,这反过来会导致"select from table A"超时。

这个想法是让第二个事务从第一个事务中读取数据,但是独立地提交/回滚。我的猜测IsolationLevel需要以某种方式改变,但我真的不明白它的选择。

修改 如果我们命名为func1和2,则可能更容易理解该问题。基本上func2是DAL功能,并且func1是对它的单元测试。 func1创建一些示例数据,获取func2以对其执行某些操作,检查结果然后将整个事情回滚,而不管func2成功与否。

EDIT2:在阅读了更多内容之后,我认为以下代码应该可以正常运行,但出于某种原因,我仍然可以在select from table A上获得超时

func1()
{
    using (var txn = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
    using (connection1)
    {
        "insert into table A"
        func2()
        "select from table B"
    }
}

func2()
{
    using (var txn = new TransactionScope(TransactionScopeOption.RequiresNew))
    using (connection2)
    {
        foreach (x in y)
        {
            "select from table A"
            "insert into table B"
        }
    }
}

2 个答案:

答案 0 :(得分:2)

你有nested TransactionScope

默认情况下,它们是链接的,没有您的进一步操作(RequiresNew),外部范围将在内部范围失败(RollBack)时发生。

这样他们就会独立:

func2()
{
    using (TransactionScope2 = 
         new TransactionScope(TransactionScopeOption.RequiresNew)) 
    using (connection2)
    {
       ...
    }
}

答案 1 :(得分:0)

尝试IsolationLevel.ReadUncommitted