繁体   English   中英

Hibernate中的并发事务

[英]Concurrent transactions in Hibernate

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

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

我有以下问题:

我必须更新tableA中的fieldA,其中MAX值为两个不同字段中的1个(tableA中的fieldA,tableB中的fieldB)

情况1:

更新前

tableA fA = 100

tableB fB = 102

更新后

tableA fA = 103

tableB fB = 102


案例2:

更新前

tableA fA = 102

tableB fB = 100

更新后

tableA fA = 103

tableB fB = 100

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

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

我怎么能这样做?

谢谢

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

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

如果使用乐观锁定,建议在实体中添加@Version字段。 不保证不支持没有版本字段的乐观锁定。

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

为了最小化lokc时间,您可以对单个查询应用锁定:

query.setLockMode(LockMode.WRITE)

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

乐观锁定是在提交时(或等效)检查数据库中的@Version字段时实现的 - 使用读提交隔离(默认),不存在丢失对实体的已提交更改的风险。

悲观锁定在数据库级别实现,通常使用SELECT FOR UPDATE或类似方法。 所以你不必担心。

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

阅读有关锁定在休眠手册中的章节

我不知道我是否理解你的问题,但也许在你的DAO中你可以准备一种方法,你可以做一些事情

DetachedCriteria dc = DetachedCriteria.forClass(ClassA);
dc.setProjection(Projections.max("id"));
logger.info(svc.getMax(dc));

获得最大值后,您可以更新另一个表

安杰洛

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM