Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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# 死锁DbContext并发事务_C#_Sql Server 2008_Entity Framework 4.1 - Fatal编程技术网

C# 死锁DbContext并发事务

C# 死锁DbContext并发事务,c#,sql-server-2008,entity-framework-4.1,C#,Sql Server 2008,Entity Framework 4.1,您好,请参见上图中的死锁图部分。我有两个更新同一个表的事务,其中一个是更新该表的长事务(同一行)5次,但另一个事务只更新该表一次,是一个两次DB命中的小事务。从死锁图可以看出,这两个事务在不同的行上都有X锁,并试图获得U锁。我无法理解为什么较短的事务acquire X lock还没有启动更新查询(因为是更新查询导致死锁,这意味着它还没有启动)。任何帮助都会让人非常满意。 1) 我使用的是隔离级别readcommitted 2) 我无法理解第二个/第一个事务如何获得X锁,而另一个事务已在某行上获得

您好,请参见上图中的死锁图部分。我有两个更新同一个表的事务,其中一个是更新该表的长事务(同一行)5次,但另一个事务只更新该表一次,是一个两次DB命中的小事务。从死锁图可以看出,这两个事务在不同的行上都有X锁,并试图获得U锁。我无法理解为什么较短的事务acquire X lock还没有启动更新查询(因为是更新查询导致死锁,这意味着它还没有启动)。任何帮助都会让人非常满意。 1) 我使用的是隔离级别readcommitted 2) 我无法理解第二个/第一个事务如何获得X锁,而另一个事务已在某行上获得X锁。我了解到,在更新查询时,首先应用U锁,然后将该特定更新行升级为X锁。现在,当一个事务具有X锁时,另一个事务如何在表扫描期间具有U锁(用于确定要更新的行)它无法通过其他事务读取具有X锁的行。3)两个事务都更新同一表的一个不同行。在不更改隔离级别的情况下,DB级别上的任何可能解决方案

我无法理解第二个/第一个事务如何获得X锁 而另一个事务已经在某行上得到了它

这就是数据库及其性能背后的魔力。锁可以在不同级别上发出,如果第二个事务没有使用表扫描,它可以发出X锁,而不会与第一个事务冲突。使用索引和表扫描搜索的更新记录可能没有发生,因此表中可能存在多个并发X锁

我读到更新查询时,首先应用U锁,然后 已升级到该特定更新行的X锁


否。更新应直接在记录上使用X锁。U锁必须由读取数据的读取查询强制执行(这就是@Marc在评论中提到的)。正如您所知,EF不支持这一点,因为它不能使用提示。

这里的经典答案是:按相同的顺序取锁;这可能涉及发出select命令,可能是UPDLOCK命令。但不确定EF是否可行。请使用SQL profiler查看事务期间执行的命令。是的,我正在使用EF,除非我们通过ExecuteStoreCommand@Marc发送查询,否则无法使用锁定提示。这是唯一的更新命令@Ladislav。如果另一个事务在同一个表上获得了X锁,那么该事务是否可能设置U锁?Update命令将导致X锁,并且在事务保持X锁完成之前,其他事务(具有您的隔离级别)不能使用该记录。非常感谢这些非常有用的建议。是的,我没有使用任何UPDLOCK提示。当我使用Select*from sys.dm_tran_Locks看到锁列表时,应用的锁在键级别只有X,在页面级别只有IX,但为什么在死锁图中它显示两个事务都在等待放置U锁。这是您必须在执行的命令中找到的。死锁图也应该显示。在将IX锁应用于更新表之后,将X个键锁应用于sys.sysconvgroup、sys.sysdesend