【发布时间】:2017-03-11 19:10:30
【问题描述】:
我已阅读有关isolation levels 的hibernate 文档,并在一个示例中使用PostgreSql 对其进行了尝试,以检查它们是否能保证并发执行同一数据集上的事务时的线程安全。我用最强的isolation level,Serializable为:
<property name="hibernate.connection.isolation">8</property>
这段代码是:
ExecutorService service = Executors.newFixedThreadPool(10);
IntStream.range(0, 20).forEach(t -> {
service.submit(() -> {
updateSalary(2L);
});
});
static void updateSalary(long id) {
Session s = sessionFactory.openSession();
org.hibernate.Transaction tx = null;
try {
tx = s.beginTransaction();
Customer c = (Customer) s.load(Customer.class, id);
c.setSalary(c.getSalary() + 10);
tx.commit();
}
catch(Exception e) {
e.printStackTrace();
tx.rollback();
}
finally {
s.close();
}
}
但是抛出异常:
org.postgresql.util.PSQLException: ERROR: could not serialize access due to concurrent update
如果我使用ReentrantLock 同步方法updateSalary():
static void updateSalary(long id) {
lock.lock();
Session s = sessionFactory.openSession();
org.hibernate.Transaction tx = null;
try {
tx = s.beginTransaction();
Customer c = (Customer) s.load(Customer.class, id);
c.setSalary(c.getSalary() + 10);
tx.commit();
}
catch(Exception e) {
e.printStackTrace();
tx.rollback();
}
finally {
s.close();
}
lock.unlock();
}
它可以工作并且是线程安全的。这是在休眠事务中实现线程安全的适当方法吗?如果没有,推荐的方法是什么?在这种情况下,如何使用Session.buildLockRequest() 实现线程安全?
【问题讨论】:
标签: java multithreading hibernate transactions