В чем разница между PESSIMISTIC_READ и PESSIMISTIC_WRITE в JPA?

Я прочитал статью " Блокировка и параллелизм в Java Persistence 2.0" и запустил пример приложения. Но я все еще не могу понять разницу между PESSIMISTIC_READ и PESSIMISTIC_WRITE. Я пытался изменить код, и где код, использующий PESSIMISTIC_READ и PESSIMISTIC_WRITE, будет иметь тот же результат, что sql будет вызываться с "для обновления".

4 ответа

Вероятно, это будет наименее технический ответ, поэтому извиняюсь, если я ошибаюсь в семантике. Но меня разочаровала сложность языка в предыдущих ответах, поэтому я решил опубликовать простой ответ:

  • PESSIMISTIC_READ: вы получаете блокировку записи в начале транзакции только для чтения. По сути, вы говорите: "Я не хочу, чтобы кто-либо обновлял эту запись, пока я ее читаю, но я не возражаю, чтобы другие читали ее". Это означает, что люди, также пытающиеся выполнить PESSIMISTIC_READ, будут успешными, но те, кто попытается выполнить PESSIMISTIC_WRITE, потерпят неудачу.

  • PESSIMISTIC_WRITE: вы получаете блокировку записи в начале транзакции с целью записи. Вы говорите: "Я собираюсь обновить эту запись, чтобы никто не мог читать или писать в нее, пока я не закончу". Это означает, что обе попытки PESSIMISTIC_READ или PESSIMISTIC_WRITE потерпят неудачу.

часть PESSIMISTIC относится к тому факту, что вы получаете блокировку в начале транзакции, т. е. перед внесением каких-либо изменений в запись, а не в конце транзакции, когда вы собираетесь зафиксировать изменения в записи.

Разница заключается в запирающем механизме.

PESSIMISTIC_READ Блокировка означает, что грязное чтение и неповторяемое чтение невозможны, если у вас есть такая блокировка. Если данные должны быть изменены, необходимо получить PESSIMISTIC_WRITE замок

PESSIMISTIC_WRITE Блокировка гарантирует, что кроме грязного и неповторяемого чтения невозможно обновить данные без получения дополнительных блокировок (и возможно). deadlocks пока жду эксклюзивной блокировки).

╔══════════════════════╦══════════════════════════╦══════════════════════════╗
║     LockModeType     ║     PESSIMISTIC_READ     ║    PESSIMISTIC_WRITE     ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣ 
║         type         ║       SHARED LOCK        ║      EXCLUSIVE LOCK      ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣   
║  isReadOnly without  ║                          ║                          ║
║   additional locks   ║            YES           ║            NO            ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║      dirty reads     ║            NO            ║            NO            ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ non-repeatable reads ║            NO            ║            NO            ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ how to update data   ║ obtain PESSIMISTIC_WRITE ║         ALLOWED          ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║                      ║       no one holds       ║      no one holds        ║
║ how to obtain lock   ║     PESSIMISTIC_WRITE    ║   PESSIMISTIC_READ   or  ║
║                      ║                          ║   PESSIMISTIC_WRITE      ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║                      ║                          ║   when there is a high   ║
║                      ║  you want to ensure no   ║ likelihood of deadlock or║
║      when to use     ║ dirty or non-repeatable  ║   update failure among   ║ 
║                      ║   reads are possible     ║    concurrent updating   ║
║                      ║                          ║       transactions       ║
╚══════════════════════╩══════════════════════════╩══════════════════════════╝

Ресурсы:

JPA 2.1

Один - это блокировка чтения, а другой - блокировка записи, или во время чтения или обновления, соответственно.

FTA:

  • PESSIMISTIC_READ. Менеджер сущностей блокирует сущность, как только транзакция читает ее. Блокировка удерживается до завершения транзакции. Этот режим блокировки используется, когда вы хотите запрашивать данные, используя семантику повторяемого чтения. Другими словами, вы хотите убедиться, что данные не обновляются между последовательными чтениями. Этот режим блокировки не блокирует другие транзакции от чтения данных.

    PESSIMISTIC_WRITE. Менеджер сущностей блокирует сущность, как только транзакция обновляет ее. Этот режим блокировки вызывает сериализацию между транзакциями, пытающимися обновить данные объекта. Этот режим блокировки часто используется, когда существует высокая вероятность сбоя обновления среди одновременных транзакций обновления.

PESSIMISTIC_READ получает общую (чтение) блокировку для связанной записи строки таблицы, в то время как PESSIMISTIC_WRITE приобретает эксклюзивный (запись) замок.

Совместная блокировка блокирует любые другие одновременные запросы исключительной блокировки, но позволяет другим запросам общей блокировки выполняться.

Эксклюзивная блокировка блокирует как общие, так и эксклюзивные запросы блокировки.

Стоит упомянуть, что для Hibernate, если база данных не поддерживает общие блокировки (например, Oracle), запрос общей блокировки (PESSIMISTIC_READ) просто получит эксклюзивный запрос блокировки (PESSIMISTIC_WRITE).

Для получения более подробной информации, прочитайте эту статью о блокировках и эту статью о JPA пессимистичных типах блокировок.

Спецификация позволяет реализации JPA использовать разные типы блокировки базы данных для каждого. Большинство баз данных имеют только один тип декларативной блокировки, поэтому в большинстве реализаций они идентичны (разницы нет).

Другие вопросы по тегам