spring管理hibernate事务3

上一节,我们介绍了如何生成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,本章没有执行事务提交。下一涨介绍事务提交的过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值