Някой може ли да ми обясни дали използваме spring за управление на транзакциите, как едновременните актуализации ще се обработват от hibernate (в паметта автоматично управление на версиите на hibernate) или трябва да поставя колона версия в базата данни, за да се погрижа ръчно за едновременните актуализации.
Независимо дали използвате Spring за управление на транзакциите или не, всъщност няма значение и не е от значение, когато става въпрос за управление на паралелност, това всъщност се обработва от Hibernate. Hibernate може да използва 2 стратегии за обработка на едновременни актуализации:оптимистично заключване и песимистично заключване.
Оптимистично
Когато използвате оптимистично заключване, вие съпоставяте специален атрибут (число, времева марка) като версия (така че всъщност имате колона за него). Тази версия се чете, когато извлечете обект и включена в клаузата where по време на актуализация и увеличава от Hibernate.
За да илюстрираме как работи това, нека си представим, че зареждате обект Person с id=1 и с текуща версия=1. След запазване Hibernate ще извърши нещо подобно:
update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;
И така, сега си представете, че имате две едновременни изпълнявани транзакции, всяка от които зарежда същото обект (същия номер на версия) и промяна на името.
Да кажем, че транзакция №1 е завършена първа, изпълнява се следната заявка:
update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;
Това е успешно и версията се увеличава.
След това транзакция №2 е завършена, изпълнява се следната заявка:
update PERSON set ID=1, NAME='NAME 2', VERSION=2 where ID=1 and VERSION=1;
Този няма да актуализира нищо, защото клаузата where няма да съответства на нито един запис. Тук ще получите оптимистично изключение за паралелност.
Тази стратегия е подходяща, когато не поддържате връзката, когато едновременните достъпи не са чести и се мащабира наистина добре. И всичко, разбира се, се обработва прозрачно от Hibernate вместо вас, стига да картографирате атрибут версия.
Песимистично
Когато използвате песимистично заключване, Hibernate заключва запис за вашата изключителна употреба, докато не приключите с него (обикновено с помощта на SELECT ... FOR UPDATE
). Всяка друга паралелна транзакция, която се опитва да получи достъп до същия запис, ще бъде спряна, докато заключването не бъде премахнато. Тази стратегия дава по-добра предсказуемост на цената на производителността и не се мащабира неограничено.
Препратки
- Справочно ръководство за ядрото на хибернация
- 11.3. Оптимистичен контрол на паралелността
- 11.4. Песимистично заключване