JPA中的PESSIMISTIC_READ和PESSIMISTIC_WRITE有什么区别?

pak*_*aka 45 java jpa locking pessimistic

我已经阅读了Java Persistence 2.0中的文章Locking and Concurrency,并运行了示例应用程序.但我仍然无法意识到PESSIMISTIC_READ和PESSIMISTIC_WRITE之间的区别.我试图修改代码,并且使用PESSIMISTIC_READ和PESSIMISTIC_WRITE的代码将具有与"for update"调用sql相同的结果.

Ser*_*hyk 45

不同之处在于锁定机制.

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       ?
??????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

资源:

JPA 2.1


Jos*_*eph 22

一个是读锁定,另一个是写锁定,或者分别在读取或更新期间.

FTA:

  • PESSIMISTIC_READ.一旦事务读取它,实体管理器就会锁定实体.锁定一直持续到事务完成.当您想使用可重复读取语义查询数据时,将使用此锁定模式.换句话说,您希望确保在连续读取之间不更新数据.此锁定模式不会阻止其他事务读取数据.

    PESSIMISTIC_WRITE.一旦事务更新实体管理器,实体管理器就会锁定该实体.此锁定模式强制尝试更新实体数据的事务之间的序列化.当并发更新事务中存在更新失败的可能性很高时,通常使用此锁定模式.

  • 谢谢,我看到了描述,但它仍然让我困惑.当我使用PESSIMISTIC_READ和PESSIMISTIC_WRITE时,它总是在"show sql"和运行结果中得到相同的结果. (2认同)

tal*_*leb 16

这可能是技术含量最低的答案,所以如果我弄错了语义,我深表歉意。但是我对之前答案中语言的复杂性感到沮丧,所以我决定发布一个简单的答案:

  • PESSIMISTIC_READ:您在事务开始时获得对记录的锁定,仅用于读取。基本上,您是在说“我不希望任何人在我阅读此记录时更新它,但我不介意其他人也阅读它”。这意味着尝试 PESSIMISTIC_READ 的人会成功,但尝试 PESSIMISTIC_WRITE 的人会失败

  • PESSIMISTIC_WRITE:您在事务开始时获得对记录的锁定,用于写入。你说的是“我将更新这个记录,所以在我完成之前没有人可以读取或写入它”。这意味着那些尝试 PESSIMISTIC_READ 或 PESSIMISTIC_WRITE 的人都将失败

悲观部分是指您在事务开始时获得锁定的事实,即在对记录进行任何更改之前,而不是在事务结束时,当您将要提交对记录的更改时。


Vla*_*cea 13

PESSIMISTIC_READ获取关于相关联的表的行记录的共享(读取)锁定,而PESSIMISTIC_WRITE获取独占(写)锁.

共享锁会阻止任何其他并发独占锁请求,但它允许其他共享锁请求继续.

独占锁会阻止共享和独占锁定请求.

值得一提的是,对于Hibernate,如果数据库不支持共享锁(例如Oracle),那么共享锁请求(PESSIMISTIC_READ)将只获取一个独占锁请求(PESSIMISTIC_WRITE).

有关更多详细信息,请查看有关锁的本文以及有关JPA悲观锁类型的本文.


Jam*_*mes 5

规范允许JPA实现为每个实现使用不同类型的数据库锁.大多数数据库只有一种类型的声明性锁,因此在大多数实现中,两者是相同的(没有区别).