Hibernate (4.1.9.Final) 和 MySQL (14.14 Distrib 5.5.29, InnoDB table)我得到了一个非常奇怪的结果:
当我使用一个线程将某些内容保存到数据库并尝试使用另一个线程获取它时,Hibernate 并不总是找到该实体。(尽管我在打开加载会话之前正确地提交了事务并关闭了持久会话。)
一些观察:
我无法使用单线程程序重现这一点。
我可以在数据库中看到“丢失”的实体,并且
如果我重新启动应用程序 Hibernate可以成功加载实体。
这是一个说明问题的 SSCCE。(为简洁起见,省略了进口):
public class StressTest {
static SessionFactory sessionFactory;
public static void main(String[] args) throws InterruptedException,
ExecutionException {
// Configure Hibernate
Configuration conf = new Configuration();
conf.setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQLInnoDBDialect");
conf.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(conf.getProperties())
.buildServiceRegistry();
sessionFactory = conf.buildSessionFactory(serviceRegistry);
// Set up producer / consumer
BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>();
new Consumer(queue).start();
new Producer(queue).start();
}
}
class DummyEntity {
long id;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
}
生产者类(创建DummyEntities
并持久化它们)。
class Producer extends Thread {
BlockingQueue<Long> sink;
public Producer(BlockingQueue<Long> sink) {
this.sink = sink;
}
@Override
public void run() {
try {
while (true) {
Session session = StressTest.sessionFactory.openSession();
DummyEntity entity = new DummyEntity();
entity.setId(new Random().nextLong());
session.beginTransaction();
session.save(entity);
session.getTransaction().commit();
session.close();
sink.put(entity.getId());
}
} catch (InterruptedException ignore) {
System.exit(-1);
}
}
}
DummyEntities
消费者类(从数据库加载):
class Consumer extends Thread {
BlockingQueue<Long> source;
public Consumer(BlockingQueue<Long> source) {
this.source = source;
}
@Override
public void run() {
try {
while (true) {
long entityId = source.take();
Session session = StressTest.sessionFactory.openSession();
Object entity = session.get(DummyEntity.class, entityId);
session.close();
if (entity == null) {
System.err.printf("Entity with id %d NOT FOUND", entityId);
System.exit(-1);
}
}
} catch (InterruptedException ignore) {
System.exit(-1);
}
}
}
最后,这是DummyEntity
.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
default-cascade="all"
default-lazy="false">
<class name="se.stresstest.DummyEntity">
<id name="id" type="long">
<generator class="assigned"/>
</id>
</class>
</hibernate-mapping>
结果输出总是以类似以下内容结束:
Entity with id -225971146115345 NOT FOUND
任何想法为什么?
(这是上一个问题的精炼版本。)