JPA 同步实体访问器

Posted

技术标签:

【中文标题】JPA 同步实体访问器【英文标题】:JPA synchronizing entity accessors 【发布时间】:2010-09-24 04:53:32 【问题描述】:

设置如下:实体类包含其他延迟加载的实体的集合。诀窍是,我需要执行一些与数据相关的工作(例如,我想用集合的元素计算某些校验和)。

这里的诀窍是我想不惜一切代价避免竞争条件,例如:“有人在我进行数据计算时更新了实体”。在正常情况下,我只会声明 getter/setter 同步并且会很高兴。但据我了解,如果另一个线程决定从数据库更新实体状态,而我正在计算校验和,它将完全忽略“同步”方法(它将直接访问该字段)。

我可能错了。所以问题是:在初始校验和计算时,有没有办法“锁定”对实体部分或整个实体本身的访问?

提前致谢! 附:如果您需要代码 sn-p 来说明问题 - 请告诉我。到目前为止,我认为这个问题很清楚。

【问题讨论】:

【参考方案1】:

我可能错了。所以问题是:在初始校验和计算时,有没有办法“锁定”对实体部分或整个实体本身的访问?

JPA 2.0 支持 pessimistic concurrency 并且您可以读取实体并在数据库级别锁定相应的行(请注意,提到的链接早于 JPA 2.0 规范的最终版本,并没有反映所有可能的值LockMode 枚举,但你明白了)。

如果您使用的是 JPA 1.0,恐怕您将不得不使用本机 SQL 来执行等效的 SELECT ... FOR UPDATE

参考文献

JPA 2.0 规范 第 3.4.4 节“锁定模式”

【讨论】:

拜托,我正在使用 JPA 2.0 Toplink 实现。无论如何,谢谢你的回答。 @Juriy 我会(稍后)。同时,下载规范并阅读我提到的部分将是一个非常好的主意 :) PS:我猜你的意思是 EclipseLink,TopLink 是 JPA 1.0 实现。 谢谢,我想我可以做到这一点。基本上我现在的主要问题是我认为我正在使用 JPA 2.0 而它是 1.0... @Juriy 然后你必须使用原生查询和SELECT ... FOR UPDATE【参考方案2】:

您还可以在实体的属性上使用@Version(适用于 JPA 1.0)

http://java.dzone.com/articles/jpa-20-concurrency-and-locking

【讨论】:

那是乐观锁定。这可能不是@Juriy 想要的,因为它将允许操作继续进行,但如果对象被另一个事务更改,则提交将失败。

以上是关于JPA 同步实体访问器的主要内容,如果未能解决你的问题,请参考以下文章

JPA工具类

将分离的实体合并到 JPA 中的实体管理器的最佳方法是啥

Java Servlet 过滤器和其他对象和实体管理器的范围

Spring JPA - 找不到实体管理器工厂,为啥?

入门 jpa--实体管理器的基本应用

JPA,实体管理器,选择多列并获取结果列表自定义对象