1

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

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

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

请建议如何解决如此长的交易问题,因为我们无法产生数千个独立的小交易,因为我们无法承受一些失败和一些成功交易的混乱数据。

4

1 回答 1

1

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

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

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

2) 更改您的数据模型以避免这些大型事务。为什么必须更新 10,000 行?也许可以将更新了这么多行的这些信息放到一个新表中,只供参考,因此您只需更新新表中的几行。

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

于 2012-07-05T12:18:46.460 回答