Я работаю над некоторыми устаревшими продуктами, и они используют таблицу для генерации уникальных ключей (первичный ключ) для каждой таблицы.Эта таблица содержит последний идентификатор для всех других таблиц.Когда они хотят вставить строку в любую другую таблицу, ниже приводится логика, которую они используют для генерации уникального идентификатора для этой новой строки
Таблица для генерации ключей выглядит как
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, так это то, что он блокирует строку при извлечении, так что нетдругая транзакция может видеть, пока она пытается обновить запись.Так что это хорошо в некластеризованной среде.Мои вопросы, будет ли это так же хорошо в кластерной среде?Будут ли какие-либо условия гонки с этим подходом?
К сожалению, мы не смогли изменить подход генерации уникальных идентификаторов из-за ограничений продукта.