选择..作为群集环境中的更新

时间:2018-11-29 05:13:44

标签: sql plsql oracle11g locking database-administration

我正在研究一些旧产品,他们正在使用一个表为每个表生成唯一键(主键)。该表包含所有其他表的最新ID。当他们想在任何其他表中插入一行时,以下是他们用来为该新行生成唯一ID的逻辑

用于生成密钥的表看起来像

 ID | NEXT_ID | TABLE_NAME

 public synchronized long generateKey(Connection con){
    // select the latest ID value from the table against a row
    // increment the value by 1
    // update the table with this latest value
    // return the latest value
 }

在单节点线程环境中,一切正常。但是在集群环境中执行上述逻辑时,需要进行更改以获取竞争条件。因此,为了解决这个问题,我们考虑使用一个Java函数来调用执行上述工作的PL / SQL函数。代码如下

 public long generateKey(Connection con) {
    // call PL/SQL function and return the value
 }

以下是PL / SQL函数的框架

 FUNCTION GET_NEXT_ID(tablename IN VARCHAR2)
 RETURN NUMBER IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    nextID NUMBER;
    BEGIN
       SELECT NEXT_ID INTO nextID FROM <Key_generator_table> WHERE TABLE_NAME=tablename FOR UPDATE;
       UPDATE <Key_generator_table> SET NEXT_ID=NEXT_ID+1 WHERE TABLE_NAME=tablename;
   commit;
   RETURN (nextID);
 END;

我对SELECT FOR UPDATE的了解是,它在我们检索时锁定行,以便在尝试更新记录时没有其他事务可以看到。因此,它在非集群环境中适用。我的问题是,在集群环境中,同样适用吗?这种方法会不会有比赛条件?

很遗憾,由于产品的限制,我们无法更改唯一ID生成方法。

1 个答案:

答案 0 :(得分:0)

这将序列化您的交易。不是一个好的设计。在您的PL / SQL函数中有序列并从中获取值怎么样?