Hibernate中的并发事务可见性

时间:2014-07-25 00:58:07

标签: java hibernate transactions isolation-level

我有一个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();
    }
}

以下是我的结果和结论:

  1. 如果MYSQL隔离级别= REPEATABLE READ,则即使启用了刷新,第二次读取也无法看到更新的值。查看新值的唯一方法是启动一个新事务,这意味着打开另一个会话。

  2. 如果MYSQL隔离级别= READ COMMITTED,那么只有在启用刷新时,第二次读取才能看到更新的值。

  3. 如果没有刷新,无论发生什么,一旦在会话期间将对象或其代理加载到持久化上下文中 - 如果对数据库的基础行进行某些并发更改,它将永远不会更新。仅仅因为Hibernate将在缓存中查找或使用代理。这意味着如果你不手动更新对象,你将永远不会看到Hibernate中的uncommited,commited,repeatable或phantom读取,无论设置了哪个隔离级别。

  4. 这是对的吗?

0 个答案:

没有答案