我应该以哪种模式锁定我的桌子?

时间:2013-07-02 15:28:37

标签: sql plsql locking

我有表EMPLOYEE(idEmp,Name,lastName,Adress),我希望以每次有人INSERTS新员工的方式阻止此表,这个新id必须连续到最后一个员工的ID。

- >实际上,可能有几个人试图在同一时间插入新员工,这就是为什么我需要锁定表...这些是替代方案:

  1. 以行共享模式锁定表EMPLOYEE。

  2. 以行独占模式锁定表EMPLOYEE。

  3. 在共享模式下锁定表EMPLOYEE。

  4. 在共享行中锁定表EMPLOYEE。

  5. 以独占模式锁定表EMPLOYEE。

  6. 我可以选择不止一个。

2 个答案:

答案 0 :(得分:6)

虽然这看起来像一个微不足道的要求,但事实并非如此。

您可能认为自动增量列或序列将提供无间隙系列但不会:插入期间遇到的任何回滚或错误都会在列中留下空白。 Sequences can never be trusted to be gap-free

在多用户环境中,为了确保获得无间隙列,您需要序列化提供数字的过程。实现这一目标的两种主要方式是:

  1. 序列化插入(在Oracle中使用LOCK TABLE IN EXCLUSIVE MODE)。正如您所料,这将无法很好地扩展。
  2. 推迟实际编号。您可以插入所需列设置为null的新行。然后会发布一个后续的单独流程:

    UPDATE my_table
       SET gap_less_id = (SELECT MAX(gap_less_id) FROM my_table) + rownum
     WHERE gap_less_id IS NULL;
    

    您需要确保此后续作业一次只运行一次(例如,参见另一个SO:Synchronisation of PL/SQL procedure. How to guaranty execution of procedure only one at time)。

    这当然意味着在提交后给予该列的值会延迟,尽管为缩放能力支付的价格可能很小。

  3. 我的第一个建议是确保无差距的要求不是虚假的。如果您在员工表中缺少id,这真的很重要吗?可能不是,这只是用于唯一标识行的主键。您可以使用其他工具计算行数,或按插入时间对行进行排名。在这种情况下,使用带有CACHE 0的序列,您不应该丢失太多ID。

    如果这是一个真正的要求,例如法律需要,那么问问自己是否可以使用其他列作为主键。如果您可以接受编号在提交之后进行后编译,则可以使用至少允许并发插入的第二种方法。

答案 1 :(得分:1)

您正在寻找的是id的“自动增量”列。在许多数据库中,您可以在create table语句中定义这样的列。 Oracle并没有这么简单,但它是可能的。

“book”解决方案是在表上定义before insert触发器。它总是会查找idEmp的值然后再添加1.出于性能原因,您将在列上定义索引。

另一种解决方案是使用序列。这被描述为here