0

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

            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

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

它似乎足够防弹,因为它是在发生任何类型的表更改之前完成的单一条件检查。然而,在对交易进行了一些阅读之后,我想知道我是否应该让我的所有程序交易以提供额外的保护。

tl博士;有没有不应该使用交易的时候?

4

3 回答 3

1

我想知道我是否应该只进行所有程序事务以提供额外的保护。

绝对不!如果这样做,您的数据库将更容易死锁,并带来相关的性能问题。

有没有不应该使用交易的时候?

单独查看每个过程,仅在绝对必要的情况下添加事务,确保事务块尽可能小。此外,确保每个事务中的表访问顺序相同。这些技巧将有助于解决死锁和性能问题。

在有问题的情况下,如果您担心有重复的客户,请添加一个唯一约束 - 您不需要在这里进行交易。

顺便说一句,FirstName、LastName 和 DateOfBirth 不适合确定真实客户数据库中的唯一性。例如,很可能有两个 John Smith 的出生日期相同。

于 2013-02-11T12:02:10.127 回答
0

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

在这种情况下,您;

  1. 检查特定行是否不存在
  2. 插入

尽管每个语句都是原子的,但任何其他语句/事务都可以在 1 和 2 之间发生,包括同一行的另一个插入。

因此,为防止这种情况,您必须围绕这两个语句使用事务以使其成为一个原子操作。

如果含义是逻辑损坏,则执行检查/修改序列的任何地方都需要事务包装器。

于 2013-02-11T12:14:49.173 回答
0

首先,UNIQUE向您的表添加一个约束(如果您还没有)。然后你就可以TRYINSERT,如果它是重复的,你会得到一个错误,你可以CATCH。这通常比预先检查重复项要简单得多,而且您不必担心事务或死锁。

于 2013-02-11T16:01:23.523 回答