Hibernate有Session和Transaction的概念,但是DB层一般只提及Transaction。
那么Hibernate的Session在DB层有相应的对应物吗?如果没有,那么Hibernate的Session有什么作用?
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或不可用,然后初始化该对象;
表沉掉啊,自顶一下吧