SQL Server防止重复

时间:2017-04-27 14:00:50

标签: sql sql-server

SQL表包含一个包含主键的表,其中包含两列:ID和Version。当应用程序尝试保存到数据库时,它使用类似于以下的命令:

BEGIN TRANSACTION

INSERT INTO [dbo].[FirstTable] ([ID],[VERSION]) VALUES (41,19)
INSERT INTO [dbo].[SecondTable] ([ID],[VERSION]) VALUES (41,19)

COMMIT TRANSACTION

SecondTable具有FirstTable的外键约束和匹配的列名。

如果两台计算机同时执行此语句,第一台计算机是否锁定FirstTable并且第二台计算机是否等待,那么当它完成等待时,它会发现第一个插入语句失败并抛出错误并且不执行第二台计算机声明?第二个插入是否可以在两台计算机上成功运行?

确保第二台计算机不写任何内容并向调用应用程序返回错误的最安全方法是什么?

3 个答案:

答案 0 :(得分:1)

由于这些是事务,所有操作必须成功,否则所有操作都会回滚。无论哪台计算机首先完成交易的第一个陈述,最终都将完成其交易。另一台计算机将尝试插入重复的主键并失败,从而导致其事务回滚。

最终,只有一台计算机会在两个表中添加一行。

答案 1 :(得分:0)

当然,如果有2个语句,那么其中一个将被执行而另一个将抛出错误。为了避免这种情况,你最好的选择是使用“如果存在”或“如果不存在” 这样做基本上是检查表中是否已存在数据,如果没有,则插入,否则只选择。

看看下面显示的流程:

if not exists (select * from Table with (updlock, rowlock, holdlock) where 
...)
/* insert */
else
/* update */

commit /* locks are released here */

答案 2 :(得分:0)

如果遇到错误,事务不会自动回滚。它需要

set xact_abort on

在这个问题中找到了这个

SQL Server - transactions roll back on error?