在 Web 组件中使用 JPA 锁
Posted
技术标签:
【中文标题】在 Web 组件中使用 JPA 锁【英文标题】:Use JPA locks in web components 【发布时间】:2016-12-05 09:06:01 【问题描述】:我了解 JPA 锁的原理(乐观和悲观),但注意到您应用于实体管理器、查询等的所有锁始终位于服务器端。所有 EJB 都位于服务器上,因此它们使用的事务也被锁定在服务器上。
假设您的电子商务网站的客户想要更改他的数据。用户在客户端(例如facelets)中填写他的更改,然后通过将它们发送到服务器来提交它们,然后服务器获得锁。但是,如果管理员在初始读取和获得锁定之前更改了客户数据怎么办?这会导致脏读
那么如何将锁定机制扩展到 Web 层? 我没有在网上找到一个选项,但是如果没有它,当前 JPA 的锁定 API 将毫无用处,不是吗?
【问题讨论】:
【参考方案1】:为了避免脏读,但不阻塞实体,可以利用 JPA 的一个称为“版本锁定”的功能,即使用其@Version 向实体类添加一个属性。
简单示例:
@Entity
public class Persona implements Serializable
//... other properties
@Version
@Column(name="VERSION")
private long version;
// getters and setters
现在,如果有人在您之前更新数据,然后尝试更新数据,JPA 引擎会抛出异常,指示其他人并更新信息。此选项可防止可能导致整个应用程序性能不佳的阻塞
【讨论】:
谢谢,但我熟悉乐观锁的概念。问题是 JPA 在每个事务结束时检查更改。好吧,这可以防止脏读,但仅限于事务期间。如果客户端在其浏览器中更改数据,则不存在这种安全性,因为没有确保其他人同时更改同一位数据的事务。以上是关于在 Web 组件中使用 JPA 锁的主要内容,如果未能解决你的问题,请参考以下文章
springboot分析——与其他组件的整合(JPA规范/atomikos/redis)
Java显式锁学习总结之二:使用AbstractQueuedSynchronizer构建同步组件