我使用的实体框架与表的每种类型。我有一个名为ins_GameAppInstances的表,它有一个针对我返回的对象类型的判别器列。还有一个表具有一些设置,这些设置具有ins_GameAppInstances的外键,名为ins_DefaultBankAccountInstances。
当我对数据库有很高的吞吐量时,带有select子查询的select和对同一个ins_GameAppInstance表的更新之间就会发生死锁。当然,sql服务器选择作为牺牲品来终止选择。
我已经绞尽脑汁了。如果您查看页面锁,就会看到page 6122和Page 4537。这可能是因为S的第一个select锁,更新在子查询select和IX锁之间,然后子查询锁定一个稍后的页面吗?这会导致僵局吗?造成这种混乱的真正原因是子查询选择?
我知道更新并没有更新与select查询结果有关的任何内容。在Server中只允许READ_COMMITTED是否安全?我并不真的想这样做,但我也不想因为实体框架和实体数据映射而改变我的域逻辑的工作方式。
更新:我在想,作为最后的手段,我可以通过尝试捕获sql异常来处理它。将异常抛到堆栈中。当我使用控制台应用程序运行我的集成测试时,需要等待死锁的发生。
catch (SqlException ex)
{
if (ex.Number == 1205)
{
if (LogManager.Enabled)
LogManager.GetLogger(GetType()).Debug("Deadlock");
}
else
throw;
}这是ins_GameAppInstance表

这是DefaultBankAccountInstance表。GameAppInstanceID是ins_GameAppInstances的外键。

这是正在发生的僵局。请求和所有者S在左边和IX请求和所有者在右边。

以下是实体框架正在构建的select和select子查询:
exec sp_executesql N'SELECT
[Join1].[CurrentWeek] AS [CurrentWeek],
[Join1].[Discriminator] AS [Discriminator],
[Join1].[ID1] AS [ID],
[Join1].[Name] AS [Name],
[Join1].[WeekHasStarted] AS [WeekHasStarted],
[Join1].[Created1] AS [Created],
[Join1].[GameAppID] AS [GameAppID],
[Join1].[GameInstanceID] AS [GameInstanceID],
[Join1].[ID2] AS [ID1]
FROM [dbo].[ins_GameAppInstances] AS [Extent1]
INNER JOIN (SELECT [Extent2].[ID] AS [ID1], [Extent2].[Name] AS [Name], [Extent2].[CurrentWeek] AS [CurrentWeek], [Extent2].[WeekHasStarted] AS [WeekHasStarted], [Extent2].[Created] AS [Created1], [Extent2].[Discriminator] AS [Discriminator], [Extent2].[GameAppID] AS [GameAppID], [Extent2].[GameInstanceID] AS [GameInstanceID], [Extent3].[ID] AS [ID2]
FROM [dbo].[ins_GameAppInstances] AS [Extent2]
LEFT OUTER JOIN [dbo].[ins_DefaultBankAccountInstances] AS [Extent3] ON [Extent2].[ID] = [Extent3].[GameAppInstanceID] ) AS [Join1] ON [Extent1].[ID] = [Join1].[ID1]
WHERE ([Extent1].[GameInstanceID] = @EntityKeyValue1) AND ([Join1].[Discriminator] IN (N''BankingAppInstance'',N''BillsAppInstance'',N''CashboxAppInstance'',N''CreditCardsAppInstance'',N''EmailsAppInstance'',N''ExpensesAppInstance'',N''RandomEventsAppInstance'',N''TextMessagesAppInstance'',N''GameAppInstance''))',N'@EntityKeyValue1 uniqueidentifier',@EntityKeyValue1='55E2A02B-73AF-4CC9-BC09-7BD46473CF4F'以下是同时发送的更新:
exec sp_executesql N'UPDATE [dbo].[ins_GameAppInstances]
SET [CurrentWeek] = @0, [WeekHasStarted] = @1
WHERE ([ID] = @2)
',N'@0 int,@1 bit,@2 uniqueidentifier',@0=4,@1=0,@2='FD00CB51-A8DD-4705-87E9-B1DD34322264'更新XML死锁文件
发布于 2016-07-25 16:21:00
根据我的经验,当您使用READ并且并发性很高时,就会出现死锁。死锁的频率将随着并发性和事务长度的增加而增加。
降低事务隔离级别可以提高某些方面,使您不会因为SELECT语句而出现死锁,但是,由于UPDATE语句,仍然有可能出现死锁。
最好的解决方案就是假设死锁是可能发生的,并且允许一定数量的重试。
https://dba.stackexchange.com/questions/147031
复制相似问题