目前我们正在使用带有 Java 和 MySQL 的 play 1.2.5。我们有一个保存到数据库中的简单 JPA 模型(一个扩展模型类的 Play 实体)。
SimpleModel() test = new SimpleModel();
test.foo = "bar";
test.save();
在每个网络请求中,我们保存 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 ]”,因为第一个请求锁定了表,但直到第二个请求超时才完成。 这导致多个:
ERROR AssertionFailure:45 - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) org.hibernate.AssertionFailure: null id in SimpleModel entry (don't flush the Session after an exception occurs)
另一个 sanitizer 是插入期间的 CPU 使用率变得疯狂。
为了解决这个问题,我正在考虑创建一个事务感知队列来按顺序插入实体,但这会导致大量的插入时间。 处理这种情况的正确方法是什么?
最佳答案
Play Framwork 1.2.5 上的 JPAPlugin 不是线程安全的,您将无法使用此版本的 Play 解决此问题。
该问题已在 Play 2.x 上修复,但如果您无法迁移,请尝试直接使用 hibernate 。
关于java - 处理多个插入的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16002200/