因此,我尝试在一个查询中,只插入一个不存在的行。
我的问题如下:
INSERT INTO [dbo].[users_roles] ([user_id], [role_id])
SELECT 29851, 1 WHERE NOT EXISTS (
SELECT 1 FROM [dbo].[users_roles] WHERE user_id = 29851 AND role_id = 1)
有时(极少发生,但仍然是这样),它会生成以下错误:
违反主键约束'PK_USERS_ROLES‘。无法在对象'dbo.users_roles‘中插入重复的键。重复键值为(29851,1)。
PK_USERS_ROLES
是[user_id], [role_id]
。下面是表模式的完整SQL:
create table users_roles
(
user_id int not null
constraint FK_USERS_ROLES_USER
references user,
role_id int not null
constraint FK_USERS_ROLES_USER_ROLE
references user_role,
constraint PK_USERS_ROLES
primary key (user_id, role_id)
)
Context:
这是由Apache服务器上托管的PHP脚本执行的,并且“随机”地发生在数百次事件中(很可能是与并发相关的)。
更多信息:
SELECT @@VERSION
给予:PHP版本:SQL Server 2008 R2
ReadCommitted
问题
happening?
谢谢。
发布于 2018-08-28 00:12:12
明确地说明这一点可能会有所帮助。下面的代码在显式事务中运行它,显式地锁定行。
DECLARE @user_id INT; SET @user_id=29851;
DECLARE @role_id INT; SET @role_id=1;
BEGIN TRY
BEGIN TRANSACTION;
DECLARE @exists INT;
SELECT @exists=1
FROM [dbo].[users_roles] WITH(ROWLOCK,HOLDLOCK,XLOCK)
WHERE user_id=@user_id AND role_id=@role_id;
IF @exists IS NULL
BEGIN
INSERT INTO [dbo].[users_roles] ([user_id], [role_id])
VALUES(@user_id,@role_id);
END
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
https://stackoverflow.com/questions/52039734
复制相似问题