我已阅读文章Locking and Concurrency in Java Persistence 2.0,并运行示例应用程序。但我仍然无法意识到PESSIMISTIC_READ和PESSIMISTIC_WRITE之间的区别。我试图修改代码,并且使用PESSIMISTIC_READ和PESSIMISTIC_WRITE的代码将具有与“for update”调用sql相同的结果。
答案 0 :(得分:42)
区别在于锁定机制。
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 ║
╚══════════════════════╩══════════════════════════╩══════════════════════════╝
资源:
答案 1 :(得分:21)
一个是读锁定,另一个是写锁定,或者分别在读取或更新期间。
FTA:
PESSIMISTIC_READ。实体经理 一旦锁定实体 交易读取它。锁是 一直持续到交易完成。 您可以在需要时使用此锁定模式 使用可重复读取来查询数据 语义。换句话说,你想要的 确保数据不是 在连续读取之间更新。 此锁定模式不会阻止其他 阅读数据的交易。
PESSIMISTIC_WRITE。实体经理 一旦锁定实体 交易更新它。这个锁 模式强制序列化 试图更新的交易 实体数据。这种锁定模式通常是 当有很高的可能性时使用 并发中的更新失败 更新交易。
答案 2 :(得分:11)
PESSIMISTIC_READ
获取关联表行记录上的共享(读取)锁定,而PESSIMISTIC_WRITE
获取独占(写入)锁定。
共享锁阻止任何其他并发独占锁请求,但它允许其他共享锁请求继续。
独占锁会阻止共享锁和独占锁请求。
值得一提的是,对于Hibernate,如果数据库不支持共享锁(例如Oracle),那么共享锁请求(PESSIMISTIC_READ
)将只获取一个独占锁请求(PESSIMISTIC_WRITE
)。
有关详细信息,请查看this article about locks和this article about JPA pessimistic lock types。
答案 3 :(得分:5)
规范允许JPA实现为每个实现使用不同类型的数据库锁。大多数数据库只有一种类型的声明性锁,因此在大多数实现中,两者是相同的(没有区别)。
答案 4 :(得分:2)
这可能是技术性最低的答案,因此,如果我弄错了语义,则表示歉意。但是我对先前答案中的语言复杂性感到沮丧,所以我决定发布一个简单的答案:
PESSIMISTIC_READ:在事务开始时,您将获得对记录的锁定,仅用于读取目的。基本上,您是说“我不希望有人在阅读时更新此记录,但我不介意其他人也阅读它”。这意味着尝试PESSIMISTIC_READ的人也会成功,但是尝试PESSIMISTIC_WRITE的人会失败
PESSIMISTIC_WRITE:出于编写目的,您在事务开始时获得了对记录的锁定。您在说的是“我将更新此记录,因此在完成之前,任何人都无法对其进行读写”。这意味着尝试PESSIMISTIC_READ或PESSIMISTIC_WRITE的尝试都将失败
PESSIMISTIC部分是指您在事务开始时即要对记录进行任何更改之前(而不是在事务结束时)将要提交对记录的更改时获得锁定的事实。