|
|
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Blazkowiczзабыл никПотому что было 30 помидоров, один заказ на 10 и второй на 10, оба вычитали что каунт = 30, первый успешно закомиттил и коунт стал 20, второй пробует сделать update count where count =30, получает отлуп, и тут уже надо разбираться? Нет ну можно замутить какой-то retry, но это усложнение с неочевидным профитом. Те варианты проще Ну, да. Всё зависит от системы и требований. Имеет ли смысл показать сообщение пользователю "ой а помидоров уже 20, а не 30", если он хотел резервировать всего 10? Где-то имеет, а где-то нет. Зависит от требований. в моем случае достаточно отнять и забыть. вот если не хватает - тогда сруо эксепшн и уже его обработать. показать типа - извините но на складе уже меньше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:28 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2Blazkowiczпропущено... Ну, да. Всё зависит от системы и требований. Имеет ли смысл показать сообщение пользователю "ой а помидоров уже 20, а не 30", если он хотел резервировать всего 10? Где-то имеет, а где-то нет. Зависит от требований. в моем случае достаточно отнять и забыть. вот если не хватает - тогда сруо эксепшн и уже его обработать. показать типа - извините но на складе уже меньше. Вы не совсем поняли, в случае с оптимистичной блокировкой(аннотация Version) эксепшен будет как в случае если помидоров реально нет, так и в случае когда их количество изменилось после того как вы прочитали их количество, но перед тем как сохранили резервацию. И этот случай вам придется обрабатывать дополнительно, ведь пользователю пофиг что их стало не 30 а 20, то есть одна аннотация вас не спасет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:31 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
забыл ник, но я же могу повторно просто чек сделать и всё. если снова вылетает я снова чек делаю и до тех пор пока либо оно не отнимет и не закоммитит резервацию либо пока меньше нуля не станет и оно не вернется сообщением юзеру. не знаю правда, как этот подход с точки зрения красоты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:36 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2но я же могу повторно просто чек сделать и всё. если снова вылетает я снова чек делаю и до тех пор пока либо оно не отнимет и не закоммитит резервацию либо пока меньше нуля не станет и оно не вернется сообщением юзеру. не знаю правда, как этот подход с точки зрения красоты. Нормальный подход, если есть гарантия выхода из цикла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:38 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Leonid Kudryavtsev Писсимистичная просто будет стоять и ждать, пока запись разблокируется. Т.е. SELECT count FROM inventory_total WHERE item_id = :id FOR UPDATE -- Поставили блокировку -- Какая-то логика UPDATE SET count=new_count inventory_total WHERE item_id = :ID COMMIT никаких exception не будет ох как всё сложно. а в туториалах всё так просто :) выходит, без скуля/хкуля никак? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:38 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2забыл ник, но я же могу повторно просто чек сделать и всё. если снова вылетает я снова чек делаю и до тех пор пока либо оно не отнимет и не закоммитит резервацию либо пока меньше нуля не станет и оно не вернется сообщением юзеру. не знаю правда, как этот подход с точки зрения красоты. Несомненно можно, выглядеть будет некрасиво и не совсем очевидно, это я сразу скажу. Но опять же все зависит от вас и от вашей системы. Лично я бы добавил просто констрейнт в базу. В крупном проекте предпочтителен вариант Leonida. Как видите проблему можно решить многими путями ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:39 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2Leonid KudryavtsevПиссимистичная просто будет стоять и ждать, пока запись разблокируется. Т.е. SELECT count FROM inventory_total WHERE item_id = :id FOR UPDATE -- Поставили блокировку -- Какая-то логика UPDATE SET count=new_count inventory_total WHERE item_id = :ID COMMIT никаких exception не будет ох как всё сложно. а в туториалах всё так просто :) выходит, без скуля/хкуля никак? Абсолютно не сложно, это и есть session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:41 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
забыл никНесомненно можно, выглядеть будет некрасиво и не совсем очевидно, это я сразу скажу. Но опять же все зависит от вас и от вашей системы. Лично я бы добавил просто констрейнт в базу. В крупном проекте предпочтителен вариант Leonida. Как видите проблему можно решить многими путями На самом деле это вполне себе красиво. Во-первых калькуляции могут быть сложнее чем обычное вычитание. И тут у нас вычисления все на Java, а не скомбинированы с QL. Это и есть цель ORM - держать логику на Java. Во-вторых повтор транзакции после OptimisticLockException это стандартная практика. Вопрос только в том до какого уровня транзакцию откатить. Констрейнта в базе это никак не отменяет, конечно. Но он нужен только для целостности данных, а не для валидации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:45 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Blazkowiczзабыл никНесомненно можно, выглядеть будет некрасиво и не совсем очевидно, это я сразу скажу. Но опять же все зависит от вас и от вашей системы. Лично я бы добавил просто констрейнт в базу. В крупном проекте предпочтителен вариант Leonida. Как видите проблему можно решить многими путями На самом деле это вполне себе красиво. Во-первых калькуляции могут быть сложнее чем обычное вычитание. И тут у нас вычисления все на Java, а не скомбинированы с QL. Это и есть цель ORM - держать логику на Java. Во-вторых повтор транзакции после OptimisticLockException это стандартная практика. Вопрос только в том до какого уровня транзакцию откатить. Констрейнта в базе это никак не отменяет, конечно. Но он нужен только для целостности данных, а не для валидации. блин. :) покажите мне плиз пример констрейнта но без примеров он апдейт на скуле. и еще вопрос: session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato); это я могу только в дао леере ставить но я в упор не понимаю где именно мне его ставить этот лок, если логика всё-равно у меня идет на сервисном леере. у меня есть две дао процедуры дао.добавить_резервацию. дао.обновить_серию (это айтем помидор) дао.прочитать_серию_с_айди_таким_то. суть процесса выглядит так: в сервисном слое. дао.прочитать_Серию_с_айди принять решение если да то дао.обновить_серию если нет то всё. куда иемнно тут вставлять строчку session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato) ???? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:50 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Blazkowiczзабыл никНесомненно можно, выглядеть будет некрасиво и не совсем очевидно, это я сразу скажу. Но опять же все зависит от вас и от вашей системы. Лично я бы добавил просто констрейнт в базу. В крупном проекте предпочтителен вариант Leonida. Как видите проблему можно решить многими путями На самом деле это вполне себе красиво. Во-первых калькуляции могут быть сложнее чем обычное вычитание. И тут у нас вычисления все на Java, а не скомбинированы с QL. Это и есть цель ORM - держать логику на Java. Во-вторых повтор транзакции после OptimisticLockException это стандартная практика. Вопрос только в том до какого уровня транзакцию откатить. Констрейнта в базе это никак не отменяет, конечно. Но он нужен только для целостности данных, а не для валидации. Да, вы правы, все зависит от системы, наше дело предложить варианты. При большой нагрузке и короткой транзакции лучше использовать пессимистическую блокировку, если сложный sql - то возможно нативный запрос или хранимка, в остальных случаях поможет оптимистическая. Просто надо понимать что серебряной пули нет, это я ТС говорю ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:51 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2Blazkowiczпропущено... На самом деле это вполне себе красиво. Во-первых калькуляции могут быть сложнее чем обычное вычитание. И тут у нас вычисления все на Java, а не скомбинированы с QL. Это и есть цель ORM - держать логику на Java. Во-вторых повтор транзакции после OptimisticLockException это стандартная практика. Вопрос только в том до какого уровня транзакцию откатить. Констрейнта в базе это никак не отменяет, конечно. Но он нужен только для целостности данных, а не для валидации. блин. :) покажите мне плиз пример констрейнта но без примеров он апдейт на скуле. и еще вопрос: session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato); это я могу только в дао леере ставить но я в упор не понимаю где именно мне его ставить этот лок, если логика всё-равно у меня идет на сервисном леере. у меня есть две дао процедуры дао.добавить_резервацию. дао.обновить_серию (это айтем помидор) дао.прочитать_серию_с_айди_таким_то. суть процесса выглядит так: в сервисном слое. дао.прочитать_Серию_с_айди принять решение если да то дао.обновить_серию если нет то всё. куда иемнно тут вставлять строчку session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato) ???? Надеюсь вы поняли что session это EntityManager? Так вот, если вы все-таки выберете вариант с пессимистеческойблокировкой, то надо делать так - создать новый метод в дао LockPomidor, в нем прописываете Код: java 1. 2. В сервис слое заменяете дао.прочитать_Серию_с_айди на дао.ЛокПомидор все остальное остается без изменений. В конце транзакции блокировка снимется автоматом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:55 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
забыл никBlazkowiczпропущено... На самом деле это вполне себе красиво. Во-первых калькуляции могут быть сложнее чем обычное вычитание. И тут у нас вычисления все на Java, а не скомбинированы с QL. Это и есть цель ORM - держать логику на Java. Во-вторых повтор транзакции после OptimisticLockException это стандартная практика. Вопрос только в том до какого уровня транзакцию откатить. Констрейнта в базе это никак не отменяет, конечно. Но он нужен только для целостности данных, а не для валидации. Да, вы правы, все зависит от системы, наше дело предложить варианты. При большой нагрузке и короткой транзакции лучше использовать пессимистическую блокировку, если сложный sql - то возможно нативный запрос или хранимка, в остальных случаях поможет оптимистическая. Просто надо понимать что серебряной пули нет, это я ТС говорю а пессимистическую блокировку в хибере можно делать только так? авторSELECT count FROM inventory_total WHERE item_id = :id FOR UPDATE -- Поставили блокировку -- Какая-то логика UPDATE SET count=new_count inventory_total WHERE item_id = :ID COMMIT т.е. я в любом случае должен буду через скуль помечать строку в таблице фор апдейт, перед тем как сравнить значения, а после того как апдейт произошел (или не произошел) я снимаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:56 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
забыл никПри большой нагрузке и короткой транзакции лучше использовать пессимистическую блокировку С этим я в корне не согласен. Большая нагрузка требует отказаться от каких либо "блокировок" вообще. Optimistic Lock ничего не блокирует. А Pessimistic Lock выстраивает транзакции в очередь и становится, если не источником проблем, то как минимум узким местом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:57 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2а пессимистическую блокировку в хибере можно делать только так? авторSELECT count FROM inventory_total WHERE item_id = :id FOR UPDATE -- Поставили блокировку -- Какая-то логика UPDATE SET count=new_count inventory_total WHERE item_id = :ID COMMIT т.е. я в любом случае должен буду через скуль помечать строку в таблице фор апдейт, перед тем как сравнить значения, а после того как апдейт произошел (или не произошел) я снимаю? Нет. Вы же привели код выше. Посмотрите в мануале, там должно быть с примерами. Раздел такой точно есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 15:58 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
ой, то есть сначала вычитываешь, потом лочишь, потом возвращаешь из дао Код: java 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:01 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Blazkowiczзабыл никПри большой нагрузке и короткой транзакции лучше использовать пессимистическую блокировку С этим я в корне не согласен. Большая нагрузка требует отказаться от каких либо "блокировок" вообще. Optimistic Lock ничего не блокирует. А Pessimistic Lock выстраивает транзакции в очередь и становится, если не источником проблем, то как минимум узким местом. Соглашусь, тогда когда бы вы рекомендовали использовать пессимистик? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:02 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
забыл никlor2пропущено... блин. :) покажите мне плиз пример констрейнта но без примеров он апдейт на скуле. и еще вопрос: session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato); это я могу только в дао леере ставить но я в упор не понимаю где именно мне его ставить этот лок, если логика всё-равно у меня идет на сервисном леере. у меня есть две дао процедуры дао.добавить_резервацию. дао.обновить_серию (это айтем помидор) дао.прочитать_серию_с_айди_таким_то. суть процесса выглядит так: в сервисном слое. дао.прочитать_Серию_с_айди принять решение если да то дао.обновить_серию если нет то всё. куда иемнно тут вставлять строчку session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_READ)).lock(tomato) ???? Надеюсь вы поняли что session это EntityManager? Так вот, если вы все-таки выберете вариант с пессимистеческойблокировкой, то надо делать так - создать новый метод в дао LockPomidor, в нем прописываете Код: java 1. 2. В сервис слое заменяете дао.прочитать_Серию_с_айди на дао.ЛокПомидор все остальное остается без изменений. В конце транзакции блокировка снимется автоматом. аллиллуя! понял. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:03 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2 т.е. я в любом случае должен буду через скуль помечать строку в таблице фор апдейт, перед тем как сравнить значения, а после того как апдейт произошел (или не произошел) я снимаю? Постарайтесь запомнить. Оптимистическая блокировка - аннотация Version. Пессимистическая - em.lock(e, LockModeType.PESSIMISTIC_READ); Как видите sql можно не писать ни там ни там, тут скорее титанические муки выбора какую же все же взять :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:04 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Blazkowiczзабыл никПри большой нагрузке и короткой транзакции лучше использовать пессимистическую блокировку С этим я в корне не согласен. Большая нагрузка требует отказаться от каких либо "блокировок" вообще. Optimistic Lock ничего не блокирует. А Pessimistic Lock выстраивает транзакции в очередь и становится, если не источником проблем, то как минимум узким местом. выходит делаем через вершн и сру? и зацикливаем (ну пусть определенное число циклов а потом всё-равно вываливаемся с сообщением типа "сервер перегружен") так выходит? прочто у меня на собесе был вопрос и там чел про вершн утверждал что надо вершн использовать. а я вообще только краем уха слыхал про этот вершен и в моих проектах там транзакции были чуть больше чем ноль по времени и в общем то никаких озадаченностей с этой стороны вообще не вызывали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:07 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
забыл никСоглашусь, тогда когда бы вы рекомендовали использовать пессимистик? Когда этого явно требует бизнес-логика приложения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:07 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2 прочто у меня на собесе был вопрос и там чел про вершн утверждал что надо вершн использовать. а я вообще только краем уха слыхал про этот вершен и в моих проектах там транзакции были чуть больше чем ноль по времени и в общем то никаких озадаченностей с этой стороны вообще не вызывали. Выбор за вами, теперь когда вы понимаете оба варианта :) Они оба приведут к поставленной цели. П,С ALTER TABLE Tomato CONSTRAINT CHK_TOMATO_NOT_NEGATIVE CHECK (count >=0); GO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 16:18 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
а такой вопрос. ексепшн при оптимистической блокировке через вершн будет выкидываться из транзакции или из метода, который применяет изменения внутри транзакции? я к чему спрашиваю - где его ловить и как обрабатывать ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 17:02 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
lor2а такой вопрос. ексепшн при оптимистической блокировке через вершн будет выкидываться из транзакции или из метода, который применяет изменения внутри транзакции? я к чему спрашиваю - где его ловить и как обрабатывать ) В идеале у вас есть 2 класса 1) Класс Domain Model отвечающий за бизнес-логику. Возможно Service. Так, вот валидация количества, перехват OptimisticLockException и его обработка это бизнес-логика. 2) Класс Repository (иногда DAO) отвечающий за доступ к ORM. Это тот самый класс, который делает UPDATE сущности и выкидывает OptimisticLockException. В идеале, конечно, надо смотреть где коммит в базу происходит. Либо на session.flush(), либо на session.commit(), либо на выходе из @Transactional метода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 17:10 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Blazkowiczпропущено... С этим я в корне не согласен. Большая нагрузка требует отказаться от каких либо "блокировок" вообще. Optimistic Lock ничего не блокирует. А Pessimistic Lock выстраивает транзакции в очередь и становится, если не источником проблем, то как минимум узким местом. Крайне спорно. На самом деле, что одно, что другое при частых конфликтах будет становится узким местом. Но если пессимистический блокировка будет тупо стоять и ждать, то оптимистическая будет неудачными ретраями забивать и апп.сервер и базу. Админ базы или надзирающая софтина пессимистическую блокировку и/или деадлок увидит, а при оптимистической - черт знает что получится на продакшене, просто 100500 бессмысленных ретраев. Блокировка - нормальная, штатная функция БД. Никаким источником проблем (при отсутвие кривых рук программистов) не становится. И незачем подменять штатные функции БД изобретенным велосипедом в виде "ретраев" IMHO На кластерах и No-SQL наверное все не совсем так... но я их за полноценные БД не считаю ))). AFAIK Оптимистическая блокировка больше придумана для GUI. Когда оператор открыл запись на редактирование и полчаса ее держит. Тогда да, оптимистическая блокировка имеет право на жизнь. IMHO & AFAIK БЕЗ приминимости к Hibernate. P.S. Архитектуру БД нужно нормальную делать. Что бы взаимных блокировок при вычислениях было меньше и деадлоки в БД на каждом шагу не возникали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 17:10 |
|
||
|
Hibernate разрешение конфликтных ситуаций?
|
|||
|---|---|---|---|
|
#18+
Leonid Kudryavtsevто оптимистическая будет неудачными ретраями забивать и апп.сервер и базу. Неудачные ретраи на много проще убрать. Leonid KudryavtsevАдмин базы или надзирающая софтина пессимистическую блокировку и/или деадлок увидит Сначала его увидят юзеры, когда блокировочная RDBMS вдруг решить что больно много у нас тут блокировок, а ну всем транзакциям стой раз-два. Leonid KudryavtsevБлокировка - нормальная, штатная функция БД. Никаким источником проблем (при отсутвие кривых рук программистов) не становится. Никто не спорит. Но чем меньше у нас блокировок тем больше у нас шансов выдержать увеличение нагрузки на систему. А чем больше у нас блокировок, тем больше у нас шансов что система встанет в самый непредвиденный момент Leonid KudryavtsevИ незачем подменять штатные функции БД изобретенным велосипедом в виде "ретраев" IMHO Это не велосипед. И как я уже указал выше, если решил повторить транзакцию, то будь уверен, что система не решит повторять её вновь и вновь. Риск от кривой реализации есть в обоих сценариях. Leonid KudryavtsevAFAIK Оптимистическая блокировка больше придумана для GUI. Когда оператор открыл запись на редактирование и полчаса ее держит. Тогда да, оптимистическая блокировка имеет право на жизнь. Об этом всём я уже написал выше в теме. Leonid KudryavtsevАрхитектуру БД нужно нормальную делать. Что бы взаимных блокировок при вычислениях было меньше и деадлоки в БД на каждом шагу не возникали. Ну, вот если на каждый пук мы будем делать SELECT FOR UPDATE, то никуда от дедлоков потом не спрячешься. А если так уж так повелось что сервер какой-нибудь MySQL, то всё ещё хуже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2016, 17:18 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39174397&tid=2124254]: |
0ms |
get settings: |
10ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
79ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
85ms |
get tp. blocked users: |
2ms |
| others: | 250ms |
| total: | 465ms |

| 0 / 0 |
