大家好问一个小疑问    今天我突然想起来一个问题,Spring是如果做到事务管理!
    大致原理是通过拦截器来做,通过拦截方法,在方法之前打开事物,在方法结束后提交关闭事物!如果没理解错大致原理应该是这样!
    然后通过创建代理类!由于工作原因没有时间来看spring源码所以提问希望大虾们能帮我解决心中的疑问!问题:
    事物打开和关闭必须是同一个session,它如何做到的给某个方法注入session?
<bean id="proxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="hibernateTransactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<!-- 用户管理代理 -->
<bean id="userManageProxy" parent="proxy">
<property name="target" ref="userManage"></property>
</bean> private static String USERTREEHQL = "from User u left join fetch u.userTrees ut left join fetch ut.tree where u.userName=? and u.passWord=?";
@SuppressWarnings("unchecked")
public User getUserTree(String userName , String passWord) {
List<User> users = getHibernateGeneralDao().find(USERTREEHQL, new Object[]{userName,passWord});
new HashSet(users);
return users.isEmpty()?null:users.get(0) ;
}
现在事物管理的代理也配置好了,在一个被管理的类中有个一个getUserTree方法,配置文件中有get*代码这个方法一定会被spring事物管理的!通过刚才我所表达的原理,spring会拦截getUserTree这个方法然后在这个方法执行之前做类似
Session session = sessionFactory.openSession();
session.beginTransaction();的动作,但是session是如何传递给这个方法的,我一直不明白!

解决方案 »

  1.   


    +1
    把session绑定到线程里,作为线程的本地变量
      

  2.   

    原来如此!我google了下,理解了,好啊,等下看还有没有更加精彩的回答
      

  3.   

    ThreadLocal和线程的区别线程是以时间还空间,ThreadLocal是以空间还时间线程如果是安全的,那么访问同一个变量需要排队,所以用时间还空间,所以效率不高
    ThreadLocal就返回来,为每一个线程提供单独的变量副本,线程之间不会出现混乱调用,这样就是空间还时间!spring管理对象时候一般都是单例,所以使用ThreadLocal来管理变量就不会出现混乱,而且效率也高!当spring使用拦截器来管理事物的时候,在通过依赖注入将当前线程的session注入到对应中的dao中,这样就轻松的实现了,个人理解的,不知道是否正确?