/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.framework.ejb.tx; import java.rmi.RemoteException; import java.util.List; import javax.ejb.ApplicationException; import org.aopalliance.intercept.MethodInvocation; import org.seasar.extension.tx.DefaultTransactionCallback; import org.seasar.extension.tx.TransactionManagerAdapter; /** * EJB3用のトランザクションコールバック実装クラスです。 * <p> * 宣言的トランザクションが適用されたメソッドから{@link ApplicationException}で注釈された例外がスローされた場合は、 * {@link ApplicationException#rollback()}の指定に従いトランザクションをロールバックするようマークします。 * </p> * * @author koichik * @since 2.4.18 */ public class EJB3TransactionCallback extends DefaultTransactionCallback { /** * @param methodInvocation * @param txRules */ @SuppressWarnings("unchecked") public EJB3TransactionCallback(final MethodInvocation methodInvocation, final List txRules) { super(methodInvocation, txRules); } @Override protected void applyTxRule(final TransactionManagerAdapter adapter, final Throwable t) { if (isRollingBack(t)) { adapter.setRollbackOnly(); return; } super.applyTxRule(adapter, t); } /** * EJB3仕様に従い、 発生した例外によってトランザクションをロールバックしなくてはならない場合は<code>true</code>を、 * それ以外の場合は<code>false</code>を返します。 * * @param throwable * 発生した例外 * @return 発生した例外によってトランザクションをロールバックしなくてはならない場合は<code>true</code> */ protected static boolean isRollingBack(final Throwable throwable) { final Class<? extends Throwable> exceptionClass = throwable.getClass(); final ApplicationException annotation = exceptionClass .getAnnotation(ApplicationException.class); if (annotation != null) { return annotation.rollback(); } if (throwable instanceof RemoteException) { return true; } if (throwable instanceof RuntimeException) { return true; } if (throwable instanceof Exception) { return false; } return true; } }