[英]How to implement persistence lock without JPA?
对于悲观锁定,JPA 最终归结为使用 JDBC 发出select * from foo where id = 1 for update
(在 MySQL 情况下)锁定 ID 1 的行。 在锁定该行的事务完成之前,没有人可以选择该行(另请参阅this which select for update在某些情况下可能锁定整个表)。 所以你可以确保只有一个人可以改变这一行。
对于乐观锁定,JPA 最终归结为首先为每条记录引入一个版本号。 Whenever a record is selected , it will also select this version number (assume the selected version is 10) . 并且每当进行更新时,它总是将此版本增加一个,并使用以下AND
条件检查该版本是否仍未被其他版本更改:
update foo set bar = xxxx , version = version + 1 where id = 1 and version = 10;
所以,如果没有记录可以更新,那意味着在你更新它之前另一个人已经改变了这个记录(即那个人已经将版本更新到 11,这使得你的AND
条件失败)。 您可以简单地向用户显示一些错误消息,并根据您的业务需求告诉他们重新加载/重试等。
我的意思是你可以简单地使用 JDBC 模拟上述方法,因为它们最后只是一些简单的 SQL 语句......
为简单起见,请使用可序列化事务锁定。 它比类似版本的锁定更容易并解决了大部分问题。
START TRANSACTION;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- do stuff
COMMIT;
Spring Framework 通过提供@Transactional
注释使您变得容易,您可以在其中指定隔离级别以及传播策略。 我发现它非常有用且易于使用。
编辑:MySQL Aurora (AWS RDS) 不支持可序列化事务隔离级别,因此请谨慎使用。
如果还不够,请参阅@Ken Chan 的回答。 根据您的问题,您关注的是concurrent edit of the entities
,所以这应该可以解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.