首页 > Hibernate的Session和Transaction问题

Hibernate的Session和Transaction问题

Hibernate有Session和Transaction的概念,但是DB层一般只提及Transaction。
那么Hibernate的Session在DB层有相应的对应物吗?如果没有,那么Hibernate的Session有什么作用?


打开mysql的general日志,写一个最普通的session访问,无事务处理,如下:

    Session session = factory.openSession();
    User user = (User)session.get(User.class, 4);
    session.close();

在日志中会看到:

    Query    SET autocommit=0
    Query    select user0_.id as id1_23_0_ ****
    Query    SHOW WARNINGS
    Query    rollback
    Query    SET autocommit=1

注意其中的"rollback",从日志来看,这个session其实是被当做一个事务发到数据库服务器的,只不过这个session最终是rollback而已;

再看一段代码:

    Session session = factory.openSession();
    User user = (User)session.get(User.class, 4);
    User user2 = (User)session.get(User.class, 5);
    User user3 = (User)session.get(User.class, 6);
    //这句话在第一个事务之前
    user.setName("AAA");
    
    Transaction tx = session.beginTransaction();
    user2.setName("BBB");
    tx.commit(); //第一个事务结束
    
    //停顿30秒
    Thread.sleep(30 * 1000);
    
    Transaction tx2 = session.beginTransaction();
    user3.setName("EEE");
    tx2.commit();
    
    System.out.println("tx:" + tx.hashCode());
    System.out.println("tx2:" + tx2.hashCode());
    
    session.close();

去数据库查看结果,(由于停顿30s)第二个事务尚未执行,但第一个事务的执行结果是user和user2的修改都生效了,这意味着第一个事务的边界实际上是从session开始到第一个tx commit,尽管从代码上看,user的修改在第一个事务边界外;

从上面两个例子来看,大致可以总结如下结论:
一个session可以包含多个事务;
事务的边界以commit为界限,跟beginTransaction关系不大;
如果代码中没写事务操作,则这个session会被当做一个rollback的事务(注意这里的前提是hibernate设置文件中connection的autocommit为false);

查看SessionImpl的源码,你会发现有个属性是currentHibernateTransaction,beginTransaction所做的事情就是检查currentHibernateTransaction是否为null或不可用,然后初始化该对象;


表沉掉啊,自顶一下吧

【热门文章】
【热门文章】