Я читал разные уровни изоляции транзакций и перешел на уровень изоляции SERIALIZABLE
. Я также знаю, что базы данных, такие как Postgres, Oracle и MySQL, поддерживают синтаксис SELECT .. FOR UPDATE
.Сериализуемые транзакции против SELECT FOR UPDATE
Я, однако, путаюсь, как они должны использоваться, когда я хотел бы заблокировать строку (или ряд строк), которые я хочу выполнить.
При использовании JPA в прошлом я всегда использовал @Transactional
в сочетании с LockModeType.PESSIMISTIC_WRITE
по запросу. Это означает использование уровня изоляции READ_COMMITTED
с помощью SELECT .. FOR UPDATE
в SQL.
Но теперь, прочитав о SERIALIZABLE
, я задаюсь вопросом, что было бы иначе, если бы я использовал @Transactional(isolation=SERIALIZABLE)
с нормальным SELECT
(например em.findById для извлечения частного лица), за которым следует UPDATE
(слияния организация).
Будет ли поведение одинаковым?
Скажите, например, у меня есть банковская система, и я хочу перевести деньги между двумя учетными записями. Я требую, чтобы эти учетные записи не вмешивались, пока передача выполняется. Итак, предположим, что я дебетую одну учетную запись на -100 и передаю ее в другой аккаунт. Каким будет лучший способ гарантировать, что эти учетные записи доступны только для транзакции, выполняющей обновление?
Предположим, что я управляю отдельными объектами JPA, поэтому перед обновлением мне придется их прочитать из БД, например. findById().
- Использование
@Transactional(isolation=READ_COMMITTED)
, em.findById сLockModeType.PESSIMISTIC_WRITE
(т.е.SELECT .. FOR UPDATE
), а затем em.merge (т.е.UPDATE
)? - ИЛИ С помощью
@Transactional(isolation=SERIALIZABLE)
, em.findById, а затем em.merge (т.е.UPDATE
)?
«* с SERIALIZABLE все всегда заблокировано *» не является истинным в качестве общего утверждения. Это сильно зависит от реализации СУБД (Postgres, например, этого не делает) –
Это правда «PostgreSQL, к примеру, не делает этого» в сериализованном PostgreSQL. Будет делать все команды выбора без блокировки, но когда происходит параллелизм в операторах записи, последняя транзакция получается не удалось обеспечить сериализуемую целостность – deFreitas