上一节,我们介绍了如何生成TransactionInfo,TransactionStatus等关键对象,引入了几个线程变量,明白了spring管理事务是如何开启事务,创建session,transaction等对象的。
本节,我们将介绍spring 如何真实执行service方法的。先贴代码
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
集中在invocation.proceedWithInvocation()
,该代码是在TransactionInterceptor.invoke()方法中的一个回调,实际执行的是AOP代理的方法
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
})
执行的就是InvocationCallback.proceedWithInvocation()方法。
AOP方法不做介绍。
通过调试,其走到了
//service代码
public PK save(T entity) {
return baseDao.save(entity);
}
//dao代码
public PK save (T entity)
{
Assert.notNull(entity, "entity is required");
return (PK) getSession().save(entity);
}
//getSession实现
public Session getSession (){
return sessionFactory.getCurrentSession();
}
以上就是业务代码。
public Session currentSession() throws HibernateException {
Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
if (value instanceof Session) {
return (Session) value;
}
else if (value instanceof SessionHolder) {
SessionHolder sessionHolder = (SessionHolder) value;
Session session = sessionHolder.getSession();
if (!sessionHolder.isSynchronizedWithTransaction() &&
TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false));
sessionHolder.setSynchronizedWithTransaction(true);
// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
// with FlushMode.MANUAL, which needs to allow flushing within the transaction.
FlushMode flushMode = SessionFactoryUtils.getFlushMode(session);
if (flushMode.equals(FlushMode.MANUAL) &&
!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.AUTO);
sessionHolder.setPreviousFlushMode(flushMode);
}
}
return session;
}
if (this.transactionManager != null) {
try {
if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
Session session = this.jtaSessionContext.currentSession();
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new SpringFlushSynchronization(session));
}
return session;
}
}
catch (SystemException ex) {
throw new HibernateException("JTA TransactionManager found but status check failed", ex);
}
}
if (TransactionSynchronizationManager.isSynchronizationActive()) {
Session session = this.sessionFactory.openSession();
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.MANUAL);
}
SessionHolder sessionHolder = new SessionHolder(session);
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));
TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
sessionHolder.setSynchronizedWithTransaction(true);
return session;
}
else {
throw new HibernateException("Could not obtain transaction-synchronized Session for current thread");
}
}
可以看到TransactionSynchronizationManager.getResource,是从线程变量中获得sessionHolder,之后再获取session
然后执行hibernate代码。执行完毕后,清理事务。此时还未真正提交事务。
cleanupTransactionInfo(txInfo);
清理事务很简单,只是将上一章的线程变量TransactionInfoHolder指向txInfo.oldTransactionInfo
总结
本章比较简单,只是执行业务代码,清理TransactionInfo,本章没有执行事务提交。下一涨介绍事务提交的过程。