/** * Copyright 2014 Duan Bingnan * * 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.pinus4j.transaction.impl; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.InvalidTransactionException; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.Status; import javax.transaction.SystemException; import javax.transaction.Transaction; import javax.transaction.TransactionManager; import org.pinus4j.transaction.enums.EnumTransactionIsolationLevel; /** * best effort one pc transaction manager implements for jta. * * @author duanbn * @since 1.1.0 */ public class BestEffortsOnePCJtaTransactionManager implements TransactionManager { private static final TransactionManager instance = new BestEffortsOnePCJtaTransactionManager(); private static final ThreadLocal<EnumTransactionIsolationLevel> txLevelLocal = new ThreadLocal<EnumTransactionIsolationLevel>(); private static final ThreadLocal<Transaction> txLocal = new ThreadLocal<Transaction>(); static { txLevelLocal.set(EnumTransactionIsolationLevel.READ_COMMITTED); } /** * get singleton instance. * * @return */ public static TransactionManager getInstance() { return instance; } public void setTransactionIsolationLevel(EnumTransactionIsolationLevel txLevel) { txLevelLocal.set(txLevel); } public EnumTransactionIsolationLevel getTransactionIsolationLevel() { return txLevelLocal.get(); } @Override public void begin() throws NotSupportedException, SystemException { Transaction tx = txLocal.get(); if (tx == null) { synchronized (this) { if (tx == null) { tx = new BestEffortsOnePCJtaTransaction(); ((BestEffortsOnePCJtaTransaction) tx).setIsolationLevel(getTransactionIsolationLevel()); txLocal.set(tx); } } } txLocal.set(tx); } @Override public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException { try { txLocal.get().commit(); } finally { // commit finished, remove transaction object from current thread. txLocal.remove(); } } @Override public int getStatus() throws SystemException { if (txLocal.get() != null) { return txLocal.get().getStatus(); } else { return Status.STATUS_NO_TRANSACTION; } } @Override public Transaction getTransaction() throws SystemException { return txLocal.get(); } @Override public void resume(Transaction arg0) throws InvalidTransactionException, IllegalStateException, SystemException { throw new UnsupportedOperationException(); } @Override public void rollback() throws IllegalStateException, SecurityException, SystemException { try { txLocal.get().rollback(); } finally { txLocal.remove(); } } @Override public void setRollbackOnly() throws IllegalStateException, SystemException { txLocal.get().setRollbackOnly(); } @Override public void setTransactionTimeout(int arg0) throws SystemException { throw new UnsupportedOperationException(); } @Override public Transaction suspend() throws SystemException { throw new UnsupportedOperationException(); } }