оптимистическое пакетное обновление - PullRequest
0 голосов
/ 26 мая 2010

Как использовать оптимистическую блокировку с пакетными обновлениями? Я использую SimpleJdbcTemplate и для одной строки я могу создать обновление SQL, которое увеличивает значение столбца версии и включает версию в предложении WHERE.

К сожалению, результат int[] updated = simpleJdbcTemplate.batchUpdate не содержит количества строк при использовании драйвера oracle. Все элементы имеют значение -2, указывающее неизвестное количество строк.

Есть ли другой, более эффективный способ сделать это, чем выполнять все обновления по отдельности? Эти партии содержат в среднем 5 единиц (только), но могут быть до 250.

1 Ответ

2 голосов
/ 29 мая 2010

Просто подумайте вслух - если это проблема с пакетной поддержкой в ​​драйвере, вы можете попытаться добиться того же, используя один запрос, что сделает пакетирование менее актуальным.(Как вы знаете, пакетирование позволяет избежать задержек с несколькими запросами, но задержка сохраняется даже при пакетировании одного запроса.)

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

  • Создайте временную таблицу, содержащую условия, необходимые для обновления строки, и перепишите свой запрос на обновление, чтобы он был соединением с этой таблицей.(Например, внешнее объединение текущей метки времени в реальных данных с меткой времени в вашей временной таблице.) Если метка времени в текущих данных не была обновлена, то строка будет выбрана из вашей временной таблицы.

Поскольку вы можете использовать временную таблицу в качестве запроса выбора, вы можете найти, какие строки будут обновлены, а затем отправить его как запрос на обновление.(Конечно, все внутри транзакции.)

Для иллюстрации:

TempUpdateTable
---------------
id,        // id of the row to be updated
timestamp, // timestamp data originally fetched
data1      // data to be updated
data2
dataN

Это дает идентификаторы всех данных, которые будут обновлены, которые вы можете сохранить для дальнейшего использования

SELECT d.id FROM TempUpdateTable t JOIN YourData d 
    ON t.id=d.id WHERE t.timestamp=d.timestamp

Тот же запрос может быть использован в операторе обновления

UPDATE YourData
SET data=t.data1
SET data=t.data2  //etc...
FROM TempUpdateTable t WHERE t.id IN
  (SELECT d.in FROM TempUpdateTable t JOIN YourData d 
    ON t.id=d.id WHERE d.timestamp=d.timestamp)
...