//Spring声明式事务可能的实现原理(AOP代理机制)
import java.lang.reflect.Method;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class TransactionInterceptor implements MethodInterceptor {
TransactionManager transactionManager;
public Object invoke(MethodInvocation invocation) throws Throwable {
Object object = invocation.getThis();
Method method = invocation.getMethod();
Object returnValue = null;
/*
* 下面的needTransaction方法用于判断当前方法是否需要事务?
* 通过object,method,以及xml配置文件来进行判断。
*/
if (needTransaction(object, method)) {
/*
* transactionManager.getTransaction()这是个关键,
* 通过事务管理器打开事务,怎么做到的?
*
* 我们知道:事务管理器需要sessionFactory,我们的Dao也需要sessionFactory,
* 而这两者都是通过容器注入的,且是同一个sessionFactory。
*
* 我们还知道:sessionFactory有一个gerCurrentSession()方法,
* 这个方法可以返回与当前线程绑定的方法
*
* 那么:如果事务管理器通过这个方法获取Session,我们的Dao也是通过这个方法获取Session,
* 那么事务管理器获得的Session和我们的Dao获取的应该是同一个Session。
*
* 所以综上所述,其实你并非必须使用HibernateTemplate,只要你容器中获取sessionFactory,
* 而后使用gerCurrentSession()方法获取Session,那时的Session就已经是打开事务的了。
*
*/
Transaction transaction = transactionManager.getTransaction();
/*
* 调用我们编写的方法,所以代理方法和我们的方法确实是运行于同一个线程上的。
*/
returnValue = method.invoke(object, invocation.getArguments());
/*
* 其实这里没这么简单,还要有异常判断以及回滚的逻辑,我这里给简化了。
*/
transaction.commit();
} else {
returnValue = method.invoke(object, invocation.getArguments());
}
return returnValue;
}
public boolean needTransaction(Object object, Method method) {
return false;
}
}
这两个是不冲突的,template是对session常用的方法的封装,让我们使用起来更简洁,方便,但是它本身没有事务的控制,事务还是的事务管理器来控制
事务管理是aop, 一般设置在service层, 一个service的方法就认为是一个事务
hibernateTemplate是HibernateDaoSupport里的东西, 是dao层的操作, 方便你写dao层代码的
HibernateTemplate自身不具有事务,只是简单封了一下session
spring的事务管理器是一个接口,hibernateTemplate是对应的实现。