我有一个Hibernate 3.6 + MySQL设置,我想检查并发事务:
package hibernate;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.*;
import org.hibernate.*;
public class HibernateGames {
public static void main(String[] args) {
//first read of the entity
Session session = HibernateUtil.getSessionFactory().openSession();
Message loaded = (Message) session.load(Message.class, 21l);
System.out.println(loaded.getText());
//here goes the concurrent update:
Session session2 = HibernateUtil.getSessionFactory().openSession();
Transaction tx2 = session2.beginTransaction();
Message loaded2 = (Message) session2.load(Message.class, 21l);
loaded2.setText("Concurrent update!!!");
tx2.commit();
session2.close();
//second read of the entity
loaded = (Message) session.load(Message.class, 21l);
// session.refresh(loaded); //refresh or not refresh the entity after concurrent update
System.out.println(loaded.getText());
session.close();
HibernateUtil.shutdown();
}
}
以下是我的结果和结论:
如果MYSQL隔离级别= REPEATABLE READ,则即使启用了刷新,第二次读取也无法看到更新的值。查看新值的唯一方法是启动一个新事务,这意味着打开另一个会话。
如果MYSQL隔离级别= READ COMMITTED,那么只有在启用刷新时,第二次读取才能看到更新的值。
如果没有刷新,无论发生什么,一旦在会话期间将对象或其代理加载到持久化上下文中 - 如果对数据库的基础行进行某些并发更改,它将永远不会更新。仅仅因为Hibernate将在缓存中查找或使用代理。这意味着如果你不手动更新对象,你将永远不会看到Hibernate中的uncommited,commited,repeatable或phantom读取,无论设置了哪个隔离级别。
这是对的吗?