目前我们正在使用带有 Java 和 MySQL 的 play 1.2.5。我们有一个简单的 JPA 模型(一个扩展 Model 类的 Play 实体),我们保存到数据库中。
SimpleModel() test = new SimpleModel();
test.foo = "bar";
test.save();
在每个 Web 请求中,我们保存多个 SimpleModel 实例,例如:
JPAPlugin.startTx(false);
for (int i=0;i<5000;i++)
{
SimpleModel() test = new SimpleModel();
test.foo = "bar";
test.save();
}
JPAPlugin.closeTx(false);
我们正在使用 JPAPlugin.startTx 和 closeTx 来手动启动和结束事务。如果只有一个请求执行事务,一切正常。我们注意到,如果第二个请求尝试同时执行循环,则第二个请求会收到“超过锁定等待超时;尝试重新启动事务 javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not insert: [SimpleModel ]”,因为第一个请求锁定了表,但直到第二个请求超时才完成。这导致多个:
错误 AssertionFailure:45 - 发生断言失败(这可能表明 Hibernate 中存在错误,但更可能是由于会话使用不安全) org.hibernate.AssertionFailure: SimpleModel 条目中的空 id(在发生异常)
另一个消毒是插入期间的 CPU 使用率变得疯狂。
为了解决这个问题,我正在考虑创建一个事务感知队列来顺序插入实体,但这会导致插入时间很长。处理这种情况的正确方法是什么?