Поэтому, пожалуйста, рассмотрите этот вопрос как разъяснение. Надеюсь, я понял это правильно, но мой английский не так хорош для понимания сложных сообщений в блогах.
И вот что я думаю, я понял из некоторых статей:
Существует два основных типа блокировки:
- оптимистическая следует использовать, когда планируется меньше операций записи. операция чтения не блокирует объект.
Например: у вас есть плавающий «денежный баланс» в сущности с оптимистической блокировкой. Теперь два процесса читают это значение и используют его для вычислений и прочего. Один из них теперь меняет значение и записывает его в базу данных с обновлением. На данный момент ошибки нет.
Но теперь другой процесс также меняет значение и хочет его обновить. Теперь есть ошибка. Это произошло только из-за второго обновления.
Если бы второй процесс удалил экземпляр, ничего бы не произошло. - пессимистично следует использовать, когда запланировано много операций записи. операция чтения заблокирует объект.
Например: у вас есть плавающий «денежный баланс» в сущности с пессимистической блокировкой. Один процесс считывает данные/значение с помощью "findOne".
После этого другой процесс также хочет прочитать данные, что было бы возможно при оптимистической блокировке, но при пессимистической блокировке он должен теперь подождите (нет ошибок, просто подождите).
Когда процесс 1 готов (изменение значения и его обновление), процесс 2 может продолжиться.
- OPTIMISTIC
- OPTIMISTIC_FORCE_INCREMENT
PESSIMISTIC_READ - PESSIMISTIC_WRITE
- PESSIMISTIC_FORCE_INCREMENT
И причем тут обновление версии? (или @version?)
Продолжаем:
Существует три основных варианта использования блокировки (в Spring jpa):
- в обычном столбце, например:
Код: Выделить всё
@Entity public class PersonEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Lock(LockModeType.PESSIMISTIC_WRITE) private String name; } - по внешнему ключу другой таблицы, например:
Код: Выделить всё
@Entity public class PersonEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Lock(LockModeType.PESSIMISTIC_WRITE) @OneToOne private Group group; } - на таблице внутри репозитория, например:
Код: Выделить всё
interface PersonRepository extends Repository { @Lock(LockModeType.PESSIMISTIC_WRITE) Person findOne(Long id); }
Код: Выделить всё
@Entity
@Lock(LockModeType.PESSIMISTIC_WRITE)
public class PersonEntity { }
Второй вопрос: правильно ли это? Я забыл об использовании блокировки?
Продолжаем:
Идея блокировки заключается в том, что другие методы/процессы должны ждать, пока блокировка снимается (кроме оптимистической блокировки, при которой выдается ошибка).
Блокировка действует до тех пор, пока экземпляр/объект активен или до следующей фиксации. p>
Существует две основные возможности разблокировать объект:
- Внутри транзакции: В этом полном методе блокировка активен. Но когда придет возврат, блокировка будет снята.
Код: Выделить всё
@Transactional public void test(){ System.out.println("start, but not locked yet"); PersonEntity person1 = personRepository.findOne(1L); // locks this person or must wait, when locked System.out.println("now locked"); // do something return true; // now the lock will be deleted -> unlocked again } - пока объект не будет удален: данные будут заблокированы, когда объект выбран, и данные будут разблокированы, когда объект будет удален. .
Код: Выделить всё
public void test(){ System.out.println("start, but not locked yet"); PersonEntity person1 = personRepository.findOne(1L); // locks this person or must wait, when locked System.out.println("now locked"); // do something person1 = null; // now the lock will be deleted -> unlocked again System.out.println("not locked anymore"); // do something more return true; }
Последние слова:
Мне действительно сложно понять такие сложные конструкции в английском языке. Я ценю любую небольшую помощь. независимо от того, даете ли вы мне ссылки для большего понимания или отвечаете на мои вопросы напрямую
Подробнее здесь: https://stackoverflow.com/questions/355 ... g-jpa-lock
Мобильная версия