aio*_*obe 6 mysql concurrency multithreading hibernate transactions
我用Hibernate(4.1.9.Final)和MySQL(14.14 Distrib 5.5.29,InnoDB表)获得了一个非常奇怪的结果:
当我使用一个线程将某些东西保存到数据库并尝试使用另一个线程获取它时,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; }
}
Run Code Online (Sandbox Code Playgroud)
生产者类(创建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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
消费者类(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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是映射的xml 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>
Run Code Online (Sandbox Code Playgroud)
结果输出总是以如下结尾:
Entity with id -225971146115345 NOT FOUND
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
(这是以前的改良版本的问题.)
| 归档时间: |
|
| 查看次数: |
612 次 |
| 最近记录: |