我得到一个极其奇怪的结果使用 Hibernate (4.1.9.Final) 和 MySQL (14.14 Distrib 5.5.29,InnoDB 表):
当我使用一个线程将某些内容持久保存到数据库并尝试使用另一个线程获取它时,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);
}
}
}
最后,这是映射-xmlDummyEntity
.
<?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
有什么想法吗?
(This is a refined version of a previous question https://stackoverflow.com/questions/15806893/threading-issues-with-hibernate.)