Я действительно не уверен, когда дело доходит до блокировки в spring jpa.
Поэтому, пожалуйста, рассмотрите этот вопрос как разъяснение. Я очень надеюсь, что я понял это правильно, но мой английский не очень хорош для понимания сложных сообщений в блогах.
Так вот что я думаю из некоторых статей:
Существует два основных типа блокировки:
- оптимистичный должен использоваться, когда запланировано меньшее количество операций записи. операция чтения не будет блокировать объект.
Например: у вас есть "денежный баланс", плавающий в объекте с оптимистичной блокировкой. Теперь два процесса читают это значение и используют его для вычисления и прочее. Один из них теперь изменяет значение и записывает его в базу данных с обновлением. Нет ошибки на данный момент.
Но теперь другой процесс также изменяет значение и хочет его обновить. Теперь есть ошибка. Это произошло только из-за второго обновления.
Если бы второй процесс удалил экземпляр, ничего бы не получилось. - pessimistic следует использовать, когда планируется большая операция записи. операция чтения заблокирует объект.
Например: у вас есть "денежный баланс", плавающий в сущности с пессимистической блокировкой. Один процесс считывает данные/значение с помощью "findOne".
После этого другой процесс хочет также прочитать данные, что было бы возможно с оптимистичной блокировкой, но с пессимистической блокировкой, которую он должен теперь ждать (нет ошибки, просто подождите).
Когда процесс 1 готов (изменение значения и его обновление), процесс 2 может продолжаться.
Первые вопросы: Это правильно? И когда я сейчас хочу протестировать это выпадение, я могу выбрать между этим LockModeType:
- ОПТИМИЗАЦИЯ
- OPTIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_READ
- PESSIMISTIC_WRITE
- PESSIMISTIC_FORCE_INCREMENT
Почему сейчас так много субблокировок и что они делают? Когда "ОПТИМИЗАЦИЯ" - это оптимистичная блокировка сверху, которую я пытался понять, то что такое "OPTIMISTIC_FORCE_INCEMENT"?
И что с этим связано обновление версии? (или @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<Person, Long> { @Lock(LockModeType.PESSIMISTIC_WRITE) Person findOne(Long id); }
Блокировка объекта напрямую с помощью
@Entity
@Lock(LockModeType.PESSIMISTIC_WRITE)
public class PersonEntity { }
невозможно. Поэтому вы можете использовать 3 (заблокировать внутри репозитория).
Второй вопрос: Это правильно? Я забыл об использовании блокировки?
Далее:
Идея блокировки заключается в том, что другим методам/процессам приходится ждать, пока блокировка не будет выпущена (за исключением оптимистической блокировки, здесь возникает ошибка).
Блокировка существует до тех пор, пока экземпляр/объект активен или до следующего фиксации.
Существуют две основные возможности для разблокировки объекта:
-
В транзакции: в этом полном методе блокировка активна. Но когда придет возврат, замок будет удален.
@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; }
Третий вопрос: насколько это правильно? Может ли эта функция действительно ждать, тогда данные заблокированы? Может ли блокировка действительно быть удалена, если для объекта установлено значение null
?
Последние слова:
Я действительно надеюсь, что никого не буду раздражать. Но, как я уже сказал, мне очень сложно понять такие сложные структуры на английском языке:(
Так что спасибо за помощь в любой форме:) Я очень ценю любую небольшую помощь. независимо от того, даете ли вы мне ссылки для более полного понимания или ответа на мои вопросы напрямую:)