Нужно сделать select, проанализировать его вывод и по результату сделать либо update и идти дальше, либо сразу вывалится из метода. Если вкратце, то эта защита от параллельного запуска некоего долго выполняющегося регламента. Сделал я метод isBusy():boolean и получается так, что два потока могут одновременно сделать select, увидеть, что регламент не запущен, затем один поток делает update(устанавливает статус регламента в "занят") и начинает его выполнение и второй поток делает то же самое. Как заблокировать выполнение этого метода средствами БД/JPA?
У меня есть идея использовать Optimistic Locking, в этом случае два потока могут сделать select, затем кто-то первый из них пишет в БД и запускает регламент, а второй при попытке записи вываливается с javax.persistence.OptimisticLock-
Exception. Такой подход правильный? Какие еще есть варианты?
Есть еще некий Programmatic Locking с его EntityManager#lock(Object entity, LockModeType type), только я вот не понимаю, как это можно использовать.
Здравствуйте, Аноним, Вы писали:
А>Нужно сделать select, проанализировать его вывод и по результату сделать либо update и идти дальше, либо сразу вывалится из метода. Если вкратце, то эта защита от параллельного запуска некоего долго выполняющегося регламента. Сделал я метод isBusy():boolean и получается так, что два потока могут одновременно сделать select, увидеть, что регламент не запущен, затем один поток делает update(устанавливает статус регламента в "занят") и начинает его выполнение и второй поток делает то же самое. Как заблокировать выполнение этого метода средствами БД/JPA?
А>У меня есть идея использовать Optimistic Locking, в этом случае два потока могут сделать select, затем кто-то первый из них пишет в БД и запускает регламент, а второй при попытке записи вываливается с javax.persistence.OptimisticLock-
А>Exception. Такой подход правильный? Какие еще есть варианты?
А>Есть еще некий Programmatic Locking с его EntityManager#lock(Object entity, LockModeType type), только я вот не понимаю, как это можно использовать.
update tbl_jobs
set running = 1
where (job_id = #id#) and (running = 0)
if (updated_rows = 1) {
start_job()
update tbl_jobs set running = 0 where (job_id = #id#)
} else {
echo "job is already started"
}
Здравствуйте, mazurkin, Вы писали:
M>M>update tbl_jobs
M> set running = 1
M> where (job_id = #id#) and (running = 0)
M>if (updated_rows = 1) {
M> start_job()
M> update tbl_jobs set running = 0 where (job_id = #id#)
M>} else {
M> echo "job is already started"
M>}
M>
Хорошая идея, только вот я в классе EntityManager не могу найти метод, который бы сделал update и вернул количество измененных строк.
On 21/10/11 18:20, Аноним 231 wrote:
> Хорошая идея, только вот я в классе EntityManager не могу найти метод, который бы сделал update и вернул количество измененных строк.
http://download.oracle.com/javaee/6/api/javax/persistence/Query.html#executeUpdate%28%29Posted via RSDN NNTP Server 2.1 beta
Здравствуйте, <Аноним>, Вы писали:
Если религия позволяет использовать возможности конкретной СУБД, и имя этой СУБД Oracle, то —
1. select ... for update nowait
2. dbms_lock
Если же религия запроещает, то
читать тут про варианты реализации
... << RSDN@Home 1.2.0 alpha 5 rev. 1526>>