首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Hibernate中的并发事务

Hibernate中的并发事务
EN

Stack Overflow用户
提问于 2014-04-30 07:08:35
回答 3查看 1.5K关注 0票数 1

我有相同的模块,连接数据库运行在两个服务器(后面和前面)。它与同一个数据库的连接。

我使用JPA (Hibernate实现)和Spring事务管理。

我有以下问题:

我必须用两个不同字段的最大值+1从fieldA更新tableA (fieldA来自tableA,fieldB来自tableB)

Case1:

更新前

tableA fA = 100

tableB fB = 102

更新后

tableA fA = 103

tableB fB = 102

Case2:

更新前

tableA fA = 102

tableB fB = 100

更新后

tableA fA = 103

tableB fB = 100

使用此代码的方法是事务性的,并在此之前(如创建实体)和之后进行操作。因此,在提交事务之前,如果其他应用程序试图获取该值,它将过时,并将在fieldA中保存相同的值。Hibernate会话是不同的,因为分布式系统。

我不能在数据库中使用序列(因为这是关于发票的法律问题)或Hibernate的分布式缓存(系统问题)。

我怎么能做到??

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-30 07:28:31

你可以用锁。适当的锁定类型取决于您的用例。

如果并发更新的概率较低,则使用乐观锁定。在发生更新冲突时,捕获Exception、刷新实体、重新应用更改并重试提交。

如果使用乐观锁定,建议将@Version字段添加到实体中。没有版本字段的乐观锁定不一定会被支持。

如果并发修改的概率很高,则使用悲观锁定。因此,可以序列化行上的写入。请注意,这种类型的锁定会造成瓶颈,因为事务队列用于更新,而其他事务则在获取锁之前超时。

为了减少lokc的时间,您可以对单个查询应用锁:

代码语言:javascript
运行
复制
query.setLockMode(LockMode.WRITE)

编辑:这些锁可能可以安全地在分布式环境中使用。

乐观锁定是在提交时(或等效)对DB中的@Version字段进行检查的方式实现的--如果使用读-预隔离(默认),则没有丢失对实体的提交更改的风险。

悲观锁定是在DB级别上实现的,通常使用SELECT FOR UPDATE或类似的。所以你不用担心。

票数 3
EN

Stack Overflow用户

发布于 2014-04-30 07:24:46

你需要止痛药锁。使用Hibernate,您可以在JDBC或事务级别上执行此操作。

阅读hibernate手册中的关于锁定的章节

票数 1
EN

Stack Overflow用户

发布于 2014-04-30 07:34:13

我不知道我是否正确地理解了你的问题,但也许在你的道上,你可以准备一种方法,这样你就可以做一些事情

代码语言:javascript
运行
复制
DetachedCriteria dc = DetachedCriteria.forClass(ClassA);
dc.setProjection(Projections.max("id"));
logger.info(svc.getMax(dc));

一旦得到最大值,就可以更新另一个表。

安杰洛

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23381799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档