大家好问一个小疑问 今天我突然想起来一个问题,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是如何传递给这个方法的,我一直不明白!
大致原理是通过拦截器来做,通过拦截方法,在方法之前打开事物,在方法结束后提交关闭事物!如果没理解错大致原理应该是这样!
然后通过创建代理类!由于工作原因没有时间来看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
把session绑定到线程里,作为线程的本地变量
ThreadLocal就返回来,为每一个线程提供单独的变量副本,线程之间不会出现混乱调用,这样就是空间还时间!spring管理对象时候一般都是单例,所以使用ThreadLocal来管理变量就不会出现混乱,而且效率也高!当spring使用拦截器来管理事物的时候,在通过依赖注入将当前线程的session注入到对应中的dao中,这样就轻松的实现了,个人理解的,不知道是否正确?