spring申明事务,就是使用一个transaction proxy factory bean将transaction inceptor编入你的业务方法。在transaction inceptor的invoke方法中,会在调用你的业务方法前begin transaction,在方法结束后,调用commit或者rollback。但是要使用hibernate的事务对象,就一定要先有一个session。所以transaction inceptor会为你打开和关闭session。这里有一个策略,就是谁打开,谁关闭。如果transaction inceptor在启动事务时,发现已经有一个session与当前线程绑定了,他就会使用这个现成的session,并且结束提交事务后,也不会关闭它。如果发现没有session与当前线程绑定,这是transaction inceptor就会open一个新的session,并且在结束方法提交后,关闭这个由它打开的session。
建议在dao方法中使用hibernate template,因为它提你完成了获得与当前线程绑定的session的操作。如果不用hibernate template,你就要使用spring的API提供的静态方法getRsource来获得session。在你业务逻辑中,绝对不要有close session的动作。因为这样会导致transaction inceptor提交事务时爆出session已关闭的异常。