当前,我们在数据层中使用JDBC,并计划用hibernate代替它。我是Hibernate的新手,不确定Hibernate如何处理并发。如果我们使用spring进行事务管理,有人可以解释一下我如何处理并发更新:通过hibernate(在内存中进行hibernate的自动版本管理),或者我必须将version列放入数据库中以手动处理并发更新。
无论你是否使用Spring进行事务管理都没有关系,并且在并发管理方面也没有关系,这实际上是由Hibernate处理的。Hibernate可以使用2种策略来处理并发更新:乐观锁定和悲观锁定。
Optimistic
使用开放式锁定时,你将特殊属性(数字,时间戳记)映射为版本(因此实际上有一个列)。检索实体时将读取此版本,并在更新过程中将其包含在where子句中并由Hibernate 递增。
为了说明这是如何工作的,我们假设你以id = 1且当前版本为1加载Person实体。保存后,Hibernate将执行以下操作:
update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;
因此,现在,假设你正在运行两个并发事务,每个事务都加载相同的实体(相同的版本号)并更改名称。
假设首先提交事务#1,然后html" target="_blank">执行以下查询:
update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;
成功,版本增加。
然后提交事务#2,执行以下查询:
update PERSON set ID=1, NAME='NAME 2', VERSION=2 where ID=1 and VERSION=1;
此语句不会更新任何内容,因为where子句与任何记录都不匹配。在这里,你将获得乐观的并发异常。
当你不维护连接,并发访问不频繁且扩展性很好时,此策略是合适的。只要映射了版本属性,Hibernate就会为你透明地处理所有内容。
Pessimistic
使用pessimistic锁定时,Hibernate会锁定记录供你独占使用,直到你完成该记录为止(通常使用SELECT ... FOR UPDATE
)。尝试访问同一记录的任何其他并发事务将被挂起,直到删除锁为止。这种策略以性能为代价提供了更好的可预测性,并且不会无限扩展。
我有一个批处理过程,它正在为一组实体重新计算数据。通过Hibernate从DB获取实体列表: 当流程运行时,某些实体似乎正在分离,导致两种症状: 当尝试获取惰性数据时,我得到一个异常: 在我的第一次尝试中,我试图通过调用inside
我有相同的模块,连接数据库运行在两个服务器(后台和前台)。它与同一个数据库连接。 我使用JPA(Hibernate实现)和Spring事务管理。 我有以下问题: 我必须用两个不同字段的最大值1更新表a中的字段a(表a中的字段a,表b中的字段b) 案例1: 更新前 表A fA = 100 tableB fB=102 更新后 表a fA=103 tableB fB=102 案例2: 更新前 表A fA
问题内容: 我有一个表,与领域,和日期时间在一个MySQL的InnoDB数据库。 每次流程获得一项工作时,它都会“签出”该工作以将其标记为已开始,以便其他任何流程都无法对其进行处理。 我希望一个会话的单个过程能够: 寻找排名最高的工作 将此作业的开始字段更新为当前时间戳 而不会冒任何其他会话也可以选择并开始排名最高的工作的风险。其他会议也随时改变排名。 这是我的尝试: 但这失败了: 无论如何,我宁
我有一个场景,我需要为1000多条记录更新日期字段。 我使用的是本机查询,但出现了错误ora-01795列表中表达式的最大数目是1000。 经过检查,我找到了一些解决方案,比如打破这个答案中提到的in条款。 但我正在寻找这个解决方案,不是一个非常干净的解决方案。 在Spring中,我还可以使用其他更干净的方法吗?请建议。 我当前的查询如下: 我传入列表的ID是从第三方API收集的。
问题内容: 由于声誉的限制,这是对先前问题的回答的后续问题。 但是想象一下一个有变化的列的大桌子。您必须比较每列,如果数据库发生更改,则必须调整触发器。而且比较硬编码的每一行都没有“感觉”好:) 是的,但这就是进行的方式。 附带说明一下,在更新之前先检查一下也是一种好习惯: 在您的示例中,这将使其更新(从而覆盖)两行而不是三行。 我想知道在处理NULL值时是否有更有效的方法来测试每个字段的更改。
我想这可能是一个新手问题,但我仍然想知道一些答案。 假设存在实体:医院和医生(多对多)。假设在我的controller类中,我必须获取所有现有的医生和医院,然后在特定的医院雇佣一名医生 它当然不起作用,因为--据我所知--我已经在控制器中获取了所有的医生和医院,然后在hireDoctor方法中,我们打开了传递常规Java对象的trasaction,这些对象不在会话中。 我知道,我可以用一个特殊的身