在插入之前检查重复时需要的交易?

时间:2013-02-11 11:55:36

标签: sql-server stored-procedures transactions

之前我创建了这个存储过程:

            Create Procedure CreateEmployee
            (
            @Role_ID Int,
            @FirstName Varchar(50),
            @LastName Varchar(50),
            @DateOfBirth Varchar(50),
            @Active Bit
            )
            As
            Begin

            If Not Exists (Select FirstName, LastName, DateOfBirth 
                From Employee Where FirstName = @FirstName
                AND LastName = @LastName
                AND DateOfBirth = @DateOfBirth)

                Begin
                Insert Into Employee (Role_ID, FirstName, LastName, DateOfBirth, Active)
                Values (@Role_ID, @FirstName, @LastName, @DateOfBirth, @Active)
                End

            Else
                Begin
                Select 'User already exists!'
                End

            End

此过程将在执行插入之前检查Employee表中是否已存在员工。

它似乎足以证明它是在进行任何类型的表更改之前完成的单个条件检查。但是在对事务进行一些阅读之后,我想知道我是否应该为了额外的保护层而进行所有程序事务。

是的;博士;有没有时间你不应该使用交易?

3 个答案:

答案 0 :(得分:1)

  

我想知道我是否应该为我的所有程序进行交易   额外的保护层。

绝对不是!如果你这样做,你将使你的数据库更有可能deadlock,并带来相关的性能问题。

  

是否有时间不使用交易?

单独查看每个过程,只添加绝对必要的事务,确保事务块尽可能小。此外,请确保每个事务中的表访问顺序相同。这些提示将有助于解决僵局和性能。

在相关案例中,如果您担心拥有重复的客户,请添加一个唯一约束 - 您不需要在此处进行交易。

顺便说一句,FirstName,LastName和DateOfBirth不利于确定真实客户数据库中的唯一性。例如,很可能有两个约翰史密斯的出生日期相同。

答案 1 :(得分:0)

数据库,如多线程程序,允许同时访问读取和修改数据。

在这种情况下你;

  1. 检查特定行不存在
  2. 插入
  3. 虽然每个语句都是原子的,但任何其他语句/事务都可以在1到2之间发生,包括同一行的另一个插入。

    因此,为了防止这种情况,你必须在两个语句周围使用一个事务来使它成为一个原子动作。

    如果影响是逻辑损坏,那么执行检查/修改序列的任何地方都需要一个事务包装器。

答案 2 :(得分:0)

首先,在表格中添加UNIQUE约束(如果尚未添加)。然后,您可以TRY INSERT,如果它是重复的,您将收到错误,CATCH。这通常比预先检查重复项更简单,您不必担心事务或死锁。