使用node.js + sequelize.js + mssql
我每5秒从3个线程做许多更新~30 (一个表)。设备轮询。
到达
SequelizeDatabaseError:事务(进程ID 57)与另一个进程在锁定资源上陷入僵局,并被选择为死锁受害者。重新运行事务。
后缀生成sql
sql:
SET IDENTITY_INSERT [DeviceCurrentData] ON;
MERGE INTO [DeviceCurrentData] WITH (HOLDLOCK) AS [DeviceCurrentData_target]
USING (
VALUES (
9,
N\ '28.300000\',
\ '2017-08-07 15:26:28.000\',
12
)
) AS [DeviceCurrentData_source]([Id], [Value], [DateStamp], [DevParamId])
ON [DeviceCurrentData_target].[Id] = [DeviceCurrentData_source].[Id]
WHEN MATCHED
THEN
UPDATE
SET [DeviceCurrentData_target].[Value] = N\ '28.300000\',
[DeviceCurrentData_target].[DateStamp] = \ '2017-08-07 15:26:28.000\',
[DeviceCurrentData_target].[DevParamId] = 12
WHEN NOT MATCHED
THEN
INSERT (
[Id],
[Value],
[DateStamp],
[DevParamId]
)
VALUES (
9,
N\ '28.300000\',
\ '2017-08-07 15:26:28.000\',
12
)
OUTPUT $ACTION,
INSERTED.*;
SET IDENTITY_INSERT [DeviceCurrentData] OFF;‘
发布于 2017-08-07 23:51:06
HOLDLOCK是一个表级锁。一旦发出,任何其他事务都不能修改表内容,直到HOLDLOCK事务完成为止。合并对并发性不利,因为合并有多个阶段,其他事务可能会陷入困境。
对于高并发性,您可能应该使用向上插入。(尝试更新,如果输出为空,则执行插入)。
此外,更新最好是针对单个行,每次使用完整的聚集索引键。如果您试图更新多个行,或者您的筛选器没有包含在索引中,那么它可能升级为一个更大的锁,并导致死锁。
减少死锁是一个复杂的话题。祝好运。
https://stackoverflow.com/questions/45553546
复制相似问题