Вставьте max + 1 из одной таблицы в две разные таблицы при пакетном обновлении из java

У меня есть требование автоматического увеличения значения в 2 таблицах со ссылочной связью. Мое требование - вставить данные в две таблицы: - Таблица A = Rowid, другие столбцы Таблица B = Rowid, другие столбцы Мне нужно вставить данные из разных методов в обе таблицы. В настоящее время я выбрал этот подход: - a. Запросите максимальное значение из таблицы A и добавьте к нему 1. б. Вставьте данные в обе таблицы со значением, полученным на шаге 1, используя пакетное обновление. Однако недостатком подхода является то, что если два пользователя/потока вызывают этот метод одновременно, они могут получить одинаковое значение, и я получу референциальную ошибку целостности в таблице A, а таблица B будет иметь 2 строки с одинаковым идентификатором строки.

Я могу синхронизировать свой метод, чтобы избежать этого, однако у меня есть несколько разных методов, которые делают то же самое из-за некоторых других функций.

Идеальный способ сделать это - использовать автоматически сгенерированный столбец, но администратор базы данных не разрешает это. Кроме того, эта ссылочная целостность между двумя таблицами должна поддерживаться приложением, фактическое ограничение не разрешено администратором баз данных.

Я использую Spring jdbctemplate на стороне Java и DB2 на стороне базы данных. Однако проблема не зависит от poth.


person Panther    schedule 30.11.2016    source источник
comment
Обратите внимание, что я знаю, что есть много вопросов, похожих на этот. Но теперь обновляются две таблицы, а также из внешнего процесса.   -  person Panther    schedule 30.11.2016
comment
Я предполагаю, что использование ПОСЛЕДОВАТЕЛЬНОСТИ или более высоких уровней изоляции не вариант. Верный?   -  person data_henrik    schedule 30.11.2016
comment
@data_henrik прав администратор базы данных просит обработать код приложения.   -  person Panther    schedule 30.11.2016


Ответы (1)


SELECT MAX()+1 – неприемлемый способ создания последовательностей для больших объемов одновременных транзакций.

Администратор базы данных, отказывающийся использовать возможности параллелизма DB2, такие как объекты ISOLATION LEVEL, IDENTITY или SEQUENCE, вызывает сожаление.

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

Оборачиваем первый оператор в FINAL TABLE, чтобы вернуть вставленные значения, включая MAX()+1, сгенерированный для TableA.rowid.

Используя ключи возврата подготовленного оператора:

PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
PreparedStatement prepareStatement(String sql, String[] columnNames)

Затем возвращенные значения применяются к TableB.rowid

person Stavr00    schedule 30.11.2016
comment
Полностью с тобой согласен. Увы, многие люди делают эту ошибку max + 1 вместо того, чтобы позволить системе управлять автоинкрементом и получать результат благодаря финальной таблице ... - person Esperento57; 30.11.2016
comment
Чувак, сбавь тон немного. На самом деле жалко, и вы не упомянули ссылочную целостность. - person danny117; 30.11.2016