Как получить значение последовательности DB2 в многопоточном приложении - PullRequest
7 голосов
/ 21 июля 2011

Я работаю над многопоточным приложением, которое использует DB2 в качестве своей основной базы данных.В прошлом мы в основном использовали столбцы Identity для таблиц, где нам требовался автоматически генерируемый уникальный идентификатор.Для этого мы выполнили бы 2 запроса в одной и той же транзакции:

INSERT INTO tbname (IDENTITY_COL, ...) VALUES (DEFAULT, ...);
SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1;

Теперь нас заставляют переключиться на последовательность.Я знаю, что вы можете использовать «СЛЕДУЮЩЕЕ ЗНАЧЕНИЕ ДЛЯ colname » как в операторах INSERT, так и в SELECT, но я не могу понять, как использовать INSERT и SELECT с одинаковыми значениями, не рискуя состязанием в многопоточном приложении.,Например, если я использую:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR SEQUENCE_COL, ...);
SELECT PREVIOUS VALUE FOR SEQUENCE_COL;

Тогда есть вероятность, что между INSERT и SELECT был запущен другой INSERT, что дает мне неправильное значение.Если я попытаюсь:

SELECT NEXT VALUE FOR SEQUENCE_COL;

сохранить значение в переменной и передать его в INSERT:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (variable_value, ...);

Тогда есть вероятность, что другой поток получит то же СЛЕДУЮЩЕЕ ЗНАЧЕНИЕ и попытаетсявведите то же значение, что приведет к ошибке DB2 -803.Можно ли использовать столбцы SEQUENCE в многопоточной среде или мне нужно бороться, чтобы сохранить мои столбцы IDENTITY?

Ответы [ 3 ]

7 голосов
/ 22 июля 2011

В дополнение к тому, что сказал Майкл Шарек (правильно):

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR SEQUENCE_COL, ...);
SELECT PREVIOUS VALUE FOR SEQUENCE_COL;

Ваше предположение Тогда есть вероятность, что между INSERT и SELECT был выполнен другой INSERT, что дает мне неправильное значение"относительно вышеуказанной последовательности операторов неверно.

" Следующее значение "и" предыдущее значение "зависят от соединения.

Доступ к последовательности из разных потоков никогда не создаст"условие гонки. Каждое соединение имеет полностью изолированную "среду" для последовательности.

6 голосов
/ 22 июля 2011

В вашем вопросе ошибочное предположение.

Если я попытаюсь:

SELECT NEXT VALUE FOR SEQUENCE_COL;

сохранить значение в переменной и передатьчто в INSERT:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (variable_value, ...);

Тогда есть вероятность, что другой поток получил то же СЛЕДУЮЩЕЕ ЗНАЧЕНИЕ и попытается вставить то же значение

Это не такправильный.Второй поток получит другое NEXTVAL, а не то же значение, что и первый поток.

Я также хочу добавить свое мнение по этой части:

На нас теперь оказывают давлениеВместо этого переключитесь на Sequence.

Я не могу представить, что есть действительно веская причина для переключения на последовательности с идентичности.Они в основном одно и то же.

2 голосов
/ 26 июня 2014

В дополнение к другим правильным ответам, вы также можете просто использовать один оператор для вставки строки и возврата вставленных значений следующим образом:

SELECT SEQUENCE_COL FROM NEW TABLE (
  INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR MY_SEQUENCE, ...)
)
...