我有表EMPLOYEE(idEmp,Name,lastName,Adress),我希望以每次有人INSERTS新员工的方式阻止此表,这个新id必须连续到最后一个员工的ID。
- >实际上,可能有几个人试图在同一时间插入新员工,这就是为什么我需要锁定表...这些是替代方案:
以行共享模式锁定表EMPLOYEE。
以行独占模式锁定表EMPLOYEE。
在共享模式下锁定表EMPLOYEE。
在共享行中锁定表EMPLOYEE。
以独占模式锁定表EMPLOYEE。
我可以选择不止一个。
答案 0 :(得分:6)
虽然这看起来像一个微不足道的要求,但事实并非如此。
您可能认为自动增量列或序列将提供无间隙系列但不会:插入期间遇到的任何回滚或错误都会在列中留下空白。 Sequences can never be trusted to be gap-free
在多用户环境中,为了确保获得无间隙列,您需要序列化提供数字的过程。实现这一目标的两种主要方式是:
LOCK TABLE IN EXCLUSIVE MODE
)。正如您所料,这将无法很好地扩展。推迟实际编号。您可以插入所需列设置为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)。
这当然意味着在提交后给予该列的值会延迟,尽管为缩放能力支付的价格可能很小。
我的第一个建议是确保无差距的要求不是虚假的。如果您在员工表中缺少id
,这真的很重要吗?可能不是,这只是用于唯一标识行的主键。您可以使用其他工具计算行数,或按插入时间对行进行排名。在这种情况下,使用带有CACHE 0
的序列,您不应该丢失太多ID。
如果这是一个真正的要求,例如法律需要,那么问问自己是否可以使用其他列作为主键。如果您可以接受编号在提交之后进行后编译,则可以使用至少允许并发插入的第二种方法。
答案 1 :(得分:1)
您正在寻找的是id的“自动增量”列。在许多数据库中,您可以在create table
语句中定义这样的列。 Oracle并没有这么简单,但它是可能的。
“book”解决方案是在表上定义before insert触发器。它总是会查找idEmp
的值然后再添加1.出于性能原因,您将在列上定义索引。
另一种解决方案是使用序列。这被描述为here。