/* * Copyright 2014 mango.jfaster.org * * The Mango Project licenses this file to you 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.jfaster.mango.transaction; import org.jfaster.mango.datasource.AbstractDataSourceFactory; import org.jfaster.mango.operator.Mango; import org.jfaster.mango.transaction.exception.CannotCreateTransactionException; import org.jfaster.mango.util.logging.InternalLogger; import org.jfaster.mango.util.logging.InternalLoggerFactory; import javax.sql.DataSource; import java.sql.Connection; import java.util.List; /** * @author ash */ public abstract class TransactionFactory { private final static InternalLogger logger = InternalLoggerFactory.getInstance(TransactionFactory.class); public static Transaction newTransaction(Mango mango, String dataSourceFactoryName, TransactionIsolationLevel level) { DataSource dataSource = mango.getMasterDataSource(dataSourceFactoryName); if (dataSource == null) { throw new IllegalArgumentException("Can't find master DataSource from mango [" + mango + "] " + "with datasource factory name [" + dataSourceFactoryName + "]"); } return newTransaction(dataSource, level); } public static Transaction newTransaction(Mango mango, String dataSourceFactoryName) { return newTransaction(mango, dataSourceFactoryName, TransactionIsolationLevel.DEFAULT); } public static Transaction newTransaction(String dataSourceFactoryName, TransactionIsolationLevel level) { List<Mango> mangos = Mango.getInstances(); if (mangos.size() != 1) { throw new IllegalStateException("The number of instances mango expected 1 but " + mangos.size() + ", " + "Please specify mango instance"); } return newTransaction(mangos.get(0), dataSourceFactoryName, level); } public static Transaction newTransaction(String dataSourceFactoryName) { return newTransaction(dataSourceFactoryName, TransactionIsolationLevel.DEFAULT); } public static Transaction newTransaction(TransactionIsolationLevel level) { return newTransaction(AbstractDataSourceFactory.DEFULT_NAME, level); } public static Transaction newTransaction() { return newTransaction(AbstractDataSourceFactory.DEFULT_NAME, TransactionIsolationLevel.DEFAULT); } public static Transaction newTransaction(DataSource dataSource) { return newTransaction(dataSource, TransactionIsolationLevel.DEFAULT); } private static Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level) { if (dataSource == null) { throw new IllegalArgumentException("DataSource can't be null"); } if (level == null) { throw new IllegalArgumentException("TransactionIsolationLevel can't be null"); } ConnectionHolder connHolder = TransactionSynchronizationManager.getConnectionHolder(dataSource); return connHolder != null ? usingExistingTransaction(dataSource) : createNewTransaction(dataSource, level); } private static Transaction usingExistingTransaction(DataSource dataSource) { if (logger.isDebugEnabled()) { logger.debug("Using existing transaction"); } Transaction transaction = new TransactionImpl(false, dataSource); return transaction; } private static Transaction createNewTransaction(DataSource dataSource, TransactionIsolationLevel expectedLevel) { if (logger.isDebugEnabled()) { logger.debug("Creating new transaction"); } Connection conn = null; try { Integer previousLevel = null; boolean isMustRestoreAutoCommit = false; conn = dataSource.getConnection(); if (logger.isDebugEnabled()) { logger.debug("Acquired Connection [" + conn + "] for JDBC transaction"); } // 设置事务的隔离级别 if (expectedLevel != TransactionIsolationLevel.DEFAULT) { previousLevel = conn.getTransactionIsolation(); if (previousLevel != expectedLevel.getLevel()) { if (logger.isDebugEnabled()) { logger.debug("Changing isolation level of JDBC Connection [" + conn + "] to " + expectedLevel.getLevel()); } conn.setTransactionIsolation(expectedLevel.getLevel()); } } // 设置自动提交为false if (conn.getAutoCommit()) { isMustRestoreAutoCommit = true; if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + conn + "] to manual commit"); } conn.setAutoCommit(false); } Transaction transaction = new TransactionImpl(true, dataSource, previousLevel, isMustRestoreAutoCommit); ConnectionHolder connHolder = new ConnectionHolder(conn); TransactionSynchronizationManager.bindConnectionHolder(dataSource, connHolder); return transaction; } catch (Throwable e) { DataSourceUtils.releaseConnection(conn, dataSource); throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", e); } } }