hibernate的session的产生方式,区别在哪里?如何产生?
session的产生方式有哪些,并且为什么要分这个?
产生流程:
1、方式一
sessionFactory.opensession():一般的crud操作我们用的是这个操作,只有增删改才用到事务,查询不需要。
sessionFactory.getCurrentSession():这个方式用的理由如下;
理由:如果有多个拥有session的方法互相调用,这个时候就存在多个session对象和多个事务了。保证不了crud操作只在一个session对象和事务中操作?这个时候寄引用到第二种方式了。
总结了两点:
session.getCurrentSession的用法
1、在hibernate的配置文件中必须加上这个才能用第二种方式:
<propertyname="current_session_context_class">thread</property>
2、不需要写session.close方法,在事务提交的时候会自动关闭(由hibernate内部完成)
3、crud都需要事务
1、因为是一个线程,所以在整个方法中有一个session和一个事务
2、保证了整个业务操作的安全性
网上针对事务为什么绑定在一起的说法:
getCurrentSession得到的session是和事务绑定的session,所以:
1,要用getCurrentSession生产的session,就必须有事务环境,意思就是你必须在调用session方法之前,session.beginTransaction();就算你只是get或者query
2,在事务提交之后,即session.getTransaction().commit()之后,session自动关闭,所以你用getCurrentSession,只需要commit事务,不要去调用session.close()。
3,你用的是ssh,spring为hibernate的current_session_context_class配置了一个SpringSessionContext来帮你管理getCurrentSession中的session,所以,你在OpenSessionInview的时候,spring就自动的帮你打开了session——>你在执行用AOP包装的事务的时候,事务就开启了——>执行你的业务方法——>提交事务(注意,hibernate管理的getCurrentSession在提交事务的时候才会关闭ession,而spring提供的这个SpringSessionContext不会)——>opensessioninview关闭session。
从上面的执行流程可以看出,你在SSH集成的时候,如果用的是getCurrentSession的集成方式,就不能设置hibernate的current_session_context_class为thread,而应该空着,让spring帮你。