我们在使用EF并行插入多个实体时遇到问题。许多进程调用WCF操作以在每次调用中生成具有不同分布式事务的实体。正如我们在sql server profiler中看到的那样,它会生成以下sql:
(@0 int,@1 nvarchar(32),@2 datetime2(7),@3 nvarchar(64),@4 int,@5 int,@6 bit)
insert [dbo].[CommandRequests](
[CommandId]
, [DeviceId]
, [StartDateTime]
, [EndDateTime]
, [Parameters]
, [Caller]
, [Result]
, [Priority]
, [Timeout]
, [ParentRequestId]
, [IsSuccessful]
, [Host])
values (@0, @1, @2, null, null, @3, null, @4, @5, null, @6, null)
select [CommandRequestId]
from [dbo].[CommandRequests]
where @@ROWCOUNT > 0 and [CommandRequestId] = scope_identity()
所以EF给我们一个插入,然后选择。因为它是并行完成的,所以很多都会被死锁中止。
我们使用的是EF 4.0,而不是4.1或4.2。
知道如何解决这个问题吗?我见过这个,但它已经很老了: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/4f634d8f-1281-430b-b664-ec7ca413b387/
答案 0 :(得分:2)
情况仍然相同。 EF没有任何其他功能可以避免这种情况。所以你的解决方案可以是:
StoreGeneratedPattern
设置为None
)。例如,您可以实现自定义HiLo Id algorithm。答案 1 :(得分:2)
最后问题在于可序列化事务中的死锁,与id的创建无关。
我在这里解释一下这个问题: http://pablocastilla.wordpress.com/2012/01/19/deadlocks-in-serializable-transactions-with-sql-server/
答案 2 :(得分:1)
我认为原因是CommandRequestId不是主键。如果将其设置为主键,则不会出现死锁。我遇到了同样的问题,当我将Identity列设置为主键时,它工作正常。