有了上面的简单介绍就可以进入真正判断是否需要事务的地方了。这个方法在TransactionAspectSupport类里,
代码
- /**
- * Create a transaction if necessary.
- * @param method method about to execute
- * @param targetClass class the method is on
- * @return a TransactionInfo object, whether or not a transaction was created.
- * The hasTransaction() method on TransactionInfo can be used to tell if there
- * was a transaction created.
- */
- protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
- // If the transaction attribute is null, the method is non-transactional.
- final TransactionAttribute sourceAttr =
- this.transactionAttributeSource.getTransactionAttribute(method, targetClass);//就是在这里判断了这个方法的事务属性
- TransactionAttribute txAttr = sourceAttr;
- // If no name specified, apply method identification as transaction name.
- if (txAttr != null && txAttr.getName() == null) {
- final String name = methodIdentification(method);
- txAttr = new DelegatingTransactionAttribute(sourceAttr) {
- public String getName() {
- return name;
- }
- };
- }
- TransactionInfo txInfo = new TransactionInfo(txAttr, method);
- //TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性
- if (txAttr != null) {
- // We need a transaction for this method
- if (logger.isDebugEnabled()) {
- logger.debug("Getting transaction for " + txInfo.joinpointIdentification());
- }
- // The transaction manager will flag an error if an incompatible tx already exists
- txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));//这个方法要仔细的看
- }
- else {
- // The TransactionInfo.hasTransaction() method will return
- // false. We created it only to preserve the integrity of
- // the ThreadLocal stack maintained in this class.
- if (logger.isDebugEnabled())
- logger.debug("Don't need to create transaction for [" + methodIdentification(method) +
- "]: this method isn't transactional");
- }
- // We always bind the TransactionInfo to the thread, even if we didn't create
- // a new transaction here. This guarantees that the TransactionInfo stack
- // will be managed correctly even if no transaction was created by this aspect.
- txInfo.bindToThread();
- return txInfo;
- }
TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性,在上面这个方法的最后,这个TransactionInfo对象被保存到当前线程中。
而这个方法会在事务拦截器TransactionInterceptor中被调用,TransactionInterceptor实际上是TransactionAspectSupport的子类,看看其中的invoke方法:
代码
- // Work out the target class: may be <code>null</code>.
- // The TransactionAttributeSource should be passed the target class
- // as well as the method, which may be from an interface
- Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;
- // Create transaction if necessary.
- TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);
- Object retVal = null;
- 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.proceed();
- }
- catch (Throwable ex) {
- // target invocation exception
- doCloseTransactionAfterThrowing(txInfo, ex);
- throw ex;
- }
- finally {
- doFinally(txInfo);
- }
- doCommitTransactionAfterReturning(txInfo);//在这里执行方法结束之后需要的操作
- return retVal;
这个方法就如同一般的interceptor需要实现的方法一样。只不过在这个方法里判断被反射的方法是否需要事务。