gpt4 book ai didi

java - 当事务更新数千个实体时如何避免 StaleObjectStateException?

转载 作者:太空宇宙 更新时间:2023-11-04 08:10:22 25 4
gpt4 key购买 nike

我们将 Hibernate 3.6.0.Final 与 JPA 2 和 Spring 3.0.5 结合使用,用于在 tomcat 7 和 MySQL 5.5 上运行的大型企业应用程序。应用程序中的大多数事务的生存时间不到一秒并更新 5-10 个实体,但在某些用例中,我们需要在单个事务中更新超过 10-20K 个实体,这需要几分钟的时间,因此超过 70% 的此类事务会因 StaleObjectStateException 失败,因为其中一些实体已被其他事务更新。

我们通常在所有表中维护版本列,如果出现 StaleObjectStateException,我们通常会重试,但由于这些长事务无论如何都很长,所以如果我们继续重试,那么我也不太确定我们是否能够逃脱 StaleObjectStateException。

此外,许多 Activity 在繁忙时间不断更新这些实体,因此我们不能采用悲观方法,因为它可能会停止系统中的许多 Activity 。

请建议如何解决这么长的交易问题,因为我们无法产生数千个独立的小交易,因为我们无法承受一些失败和一些成功交易的情况下困惑的数据。

最佳答案

在一次事务中修改 20,000 个实体确实很多,比正常情况要多得多。

我无法给您一个通用的解决方案,但这里有一些解决问题的想法。

1) 使用LockMode.UPGRADE(参见pessimistic locking)。在那里,您显式生成“SELECT FOR UPDATE”,这会阻止其他用户在锁定时修改行。这应该可以避免您的问题,但如果您有太多大型事务,则可能会产生死锁(取决于您的编程)或超时。

2) 更改数据模型以避免这些大型事务。为什么必须更新 10,000 行?也许可以将这些更新了这么多行的信息放入一个新表中并让它仅被引用,这样您只需更新新表中的几行。

3)使用StatelessSession代替Session。在这种情况下,您不会在异常后被迫回滚,而是可以纠正问题并继续(在您的情况下重新加载同时修改的实体,并在重新加载的实体上对大型事务进行修改)。这也许使您能够逐行处理关键事件(同时修改行),而不是处理完整的大型事务。

关于java - 当事务更新数千个实体时如何避免 StaleObjectStateException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11331718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com