【问题标题】:Two parallel TransactionScope each with it's own connection两个并行的 TransactionScope,每个都有自己的连接
【发布时间】:2010-12-12 18:30:43
【问题描述】:

我试图弄清楚 TransactionScope 如何使用代表不同事务场景的示例代码来工作...
你能解释一下当我有 2 个并发 TransactionScopes 每个都有自己的连接时,日期实际发生了什么?就像在这个示例代码中一样:

internal class Program
{
    private const int Count = 20;
    private static readonly Random Random = new Random();

    private static void Main(string[] args)
    {
        var task1 = new Task(Task1);
        var task2 = new Task(Task2);
        task1.Start();
        task2.Start();
        Console.ReadLine();
    }
    private static void Task1()
    {
        var connection = new EntityConnection("name=ModelContainer");
        using (var transaction = new TransactionScope())
        {
            DoWork(connection);
            transaction.Complete();
        }
    }
    private static void Task2()
    {
        var connection = new EntityConnection("name=ModelContainer");
        using (var transaction = new TransactionScope())
        {
            DoWork(connection);
            transaction.Complete();
        }
    }
    private static void DoWork(EntityConnection connection)
    {
        connection.Open();
        using (var context = new ModelContainer(connection))
        {
            List<SyncData> list = context.SyncDataSet.ToList();
            for (int i = 0; i < Count; i++)
            {
                list[i].Knowledge.Version = Random.Next(200);
                context.SaveChanges();
            }
        }
    }
}

【问题讨论】:

    标签: c# entity-framework transactions transactionscope


    【解决方案1】:

    嵌套(并且在同一个线程上)的事务范围成为同一个事务的一部分(外部事务是完成的定义范围) - 如果需要,升级到 DTC。在您的情况下,事务似乎没有嵌套,因此它们是不相关的。这也应该意味着 LTM 而不是 DTC 是所有者,它的开销更少。

    因此,当然,如果它们触及相同的数据,您可能需要注意它们之间的阻塞等。特别是因为事务范围默认为可序列化隔离。

    【讨论】:

    • 它们是不相关的,但是这里的数据发生了什么?理论上事务是隔离的,所以第一个事务应该创建“数据库副本”并修改这个副本,在第一个事务创建之后,第二个被创建并且应该具有相同的数据副本,因为它是在第一次提交之前创建的。然后第一次提交它的数据,然后第二次提交它的数据,所以基本上我应该有最后一个要提交的事务的数据,但在这段代码中,结果是死锁。
    • @Broken 确实;这里的 read 只是一个读锁,所以很可能出现死锁。如果我正在编写 TSQL,我会添加会导致阻塞而不是死锁的 UPDLOCK。我不知道你是否可以将 UPDLOCK 添加到 EF 读取中
    • @Broken re 场景 - 如果第二个线程有读锁,第一次提交就不会发生。上面的 UPDLOCK 建议将通过防止第二个线程读取数据直到第一个线程完成它的工作来工作。
    猜你喜欢
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2015-02-04
    • 2013-08-23
    • 2011-05-21
    相关资源
    最近更新 更多