1

我有表 EMPLOYEE (idEmp,Name,lastName,Adress),我想阻止这个表,每次有人插入新员工时,这个新 id 必须与最后一个员工的 ID 连续......

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

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

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

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

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

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

我可以选择不止一个。

4

2 回答 2

6

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

您可能认为自动增量列或序列将提供无间隙系列,但事实并非如此:插入期间遇到的任何回滚或错误都会在列中留下间隙。永远不能相信序列是无间隙的

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

  1. 序列化插入(在 Oracle 中带有LOCK TABLE IN EXCLUSIVE MODE)。正如您所料,这不会很好地扩展。
  2. 推迟实际编号。您将插入所需列设置为空的新行。然后将发出后续的单独流程:

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

    您需要确保此后续作业在任何时候仅运行一次(例如参见另一个 SO:PL/SQL 过程的同步。如何保证每次只执行一个过程)。

    这当然意味着赋予该列的值在提交后会延迟,尽管为扩展能力付出的代价可能很小。

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

如果这是一个真实的需求,比如法律需要,那么问问自己是否可以使用另一列作为主键。如果您可以接受将编号推迟到提交之后,您可以使用至少允许并发插入的第二种方法。

于 2013-07-02T15:54:03.817 回答
1

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

“书”解决方案是在表上定义一个插入前触发器。它总是查找 的值,idEmp然后加 1。出于性能原因,您将在列上定义一个索引。

另一种解决方案是使用序列。这在此处进行了描述。

于 2013-07-02T15:39:29.707 回答