JPA 同步实体访问器
设置如下:实体类具有延迟加载的其他实体的集合。诀窍是,我需要执行一些与数据相关的工作(例如,我想使用集合的元素计算某些校验和)。
这里的技巧是,我想不惜一切代价避免竞争条件,例如:“在我进行数据计算时有人更新了实体”。在正常情况下,我只会声明 getter/setter 同步并且对此感到满意。但据我了解,如果另一个线程决定从数据库更新实体状态,当我正在计算校验和时,它将完全忽略“同步”方法(它将直接访问该字段)。
我可能错了。所以问题是:有没有办法在初始校验和计算时“锁定”对实体的一部分或整个实体本身的访问?
提前致谢! PS 如果您需要代码片段来说明问题 - 请告诉我。到目前为止,我认为这个问题已经很清楚了。
Here's the setup: the entity class has the collection of other entities that is loaded lazily. The trick is, I need to perform some data-related work (for example, I want to calculate certain checksum with the elements of collection).
The trick here is that I want to avoid at all costs the race conditions like: "someone has updated the entity while I was making my data calculations". In the normal circumstances I'll just declare getter/setter synchronized and will be happy with it. BUT as far as I understand, if the other thread decides to update the entity state from the database, while I'm in the middle of calculating my checksum it will completely ignore the "synchronized" methods (it will access the field directly).
I might be wrong tough. So the question is: is there any way to "lock" the access to the part of the entity or to the whole entity itself for the time of initial checksum calculations?
Thanks in advance!
P.S. If you need a code snippet to illustrate the problem - just let me know. So far I think the question is pretty clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
JPA 2.0 支持悲观并发,您可以读取实体并锁定数据库级别的相应行(请注意,提到的链接早于 JPA 2.0 规范的最终版本,并且不反映
LockMode
枚举的所有可能值,但您明白了)。如果您使用 JPA 1.0,恐怕您将不得不使用本机 SQL 来执行等效的 SELECT ... FOR UPDATE 。
参考
JPA 2.0 supports pessimistic concurrency and you can read an entity and lock the corresponding row at the database level (note that the mentioned linked predates the final version of the JPA 2.0 specification and doesn't reflect all the possible values of the
LockMode
enum, but you get the idea).And if you are using JPA 1.0, I'm afraid you'll have to use native SQL to perform the equivalent
SELECT ... FOR UPDATE
.References
您还可以在实体的属性上使用@Version(适用于JPA 1.0)
http://java.dzone.com/articles/jpa-20-concurrency-and-locking
You can also use @Version on an attribute of your Entity (works in JPA 1.0)
http://java.dzone.com/articles/jpa-20-concurrency-and-locking