Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据库死锁和事务隔离级别_C#_Sql Server_Transactions_Deadlock - Fatal编程技术网

C# 数据库死锁和事务隔离级别

C# 数据库死锁和事务隔离级别,c#,sql-server,transactions,deadlock,C#,Sql Server,Transactions,Deadlock,下面是我的代码,它打开一个事务并向表中插入一行,同时打开另一个连接并查询同一个表。程序在第(*)行挂起 在我的数据库上,事务隔离级别为ReadCommitted。我希望计数为0 看起来连接1锁定了表,因此连接2无法读取它。如果这是真的,为什么会有事务隔离级别?您有一个打开事务的第一个连接,将新行插入表中,不会提交。该表上有任意数量和种类的不可共享锁 然后有第二个连接尝试读取计数 是的,这将导致死锁(在应用程序层,而不是SQL层)。这些连接是完全不相关的(除非您有一个您没有提到的环境Transac

下面是我的代码,它打开一个事务并向表中插入一行,同时打开另一个连接并查询同一个表。程序在第(*)行挂起

在我的数据库上,事务隔离级别为
ReadCommitted
。我希望计数为0


看起来连接1锁定了表,因此连接2无法读取它。如果这是真的,为什么会有事务隔离级别?

您有一个打开事务的第一个连接,将新行插入表中,不会提交。该表上有任意数量和种类的不可共享锁

然后有第二个连接尝试读取计数

是的,这将导致死锁(在应用程序层,而不是SQL层)。这些连接是完全不相关的(除非您有一个您没有提到的环境
TransactionScope
),因此第二个连接将被阻止。在提交之前,它无法告诉您计数,因为它是
ReadCommitted
——这意味着它只能读取提交的数据。直到那时:它需要等待


如果您明确希望读取超过锁,请使用较低的隔离级别,例如
readuncommitted
,或添加一个显式
NOLOCK
提示。

这是读提交的隔离级别的定义行为


看看维基百科的文章:

哦,我找到了。
将READ\u COMMITTED\u SNAPSHOT设置为ON
会解决死锁吗?@LoveRight这是。。。这不是修复死锁的好方法。在我看来,有3种很好的方法可以解决这个问题:1)在事务使用的同一个连接上执行计数(这将为您提供新的计数);2) 重新构造代码,这样你就不会这样做了——在这里留下一个打开的事务是一种非常糟糕的气味——但是如果你需要等待(获得可靠的值),那么等待;3) 如果必须通过锁读取,请使用较低的隔离;快照可能会解决这个问题,但其原因基本上是尖叫“我不明白发生了什么”——这从来都不好——我只是在做实验。谢谢
//TestTable is empty.
using (connection1 == new SqlConnection(OpConsoleLib.std.CONNECTIONSTRING)) {
    connection1.Open();
    SqlCommand cmd = new SqlCommand("Insert into TestTable values('hello')", connection1);
    cmd.Transaction = connection1.BeginTransaction();
    cmd.ExecuteNonQuery()

    using (SqlConnection connection2 = new SqlConnection(OpConsoleLib.std.CONNECTIONSTRING)) {
        connection2.Open();
        SqlCommand cmd2 = new SqlCommand("Select count(*) from TestTable where name='hello'", connection2); //(*)

        int count=Convert.ToInt32(cmd2.ExecuteScalar());

    }

    cmd.Transaction.Commit();
}