001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.sqlmap.engine.transaction.jta;
017:
018: import com.ibatis.common.jdbc.logging.ConnectionLogProxy;
019: import com.ibatis.common.logging.Log;
020: import com.ibatis.common.logging.LogFactory;
021: import com.ibatis.sqlmap.engine.transaction.IsolationLevel;
022: import com.ibatis.sqlmap.engine.transaction.Transaction;
023: import com.ibatis.sqlmap.engine.transaction.TransactionException;
024:
025: import javax.sql.DataSource;
026: import javax.transaction.Status;
027: import javax.transaction.UserTransaction;
028: import java.sql.Connection;
029: import java.sql.SQLException;
030:
031: public class JtaTransaction implements Transaction {
032:
033: private static final Log connectionLog = LogFactory
034: .getLog(Connection.class);
035:
036: private UserTransaction userTransaction;
037: private DataSource dataSource;
038: private Connection connection;
039: private IsolationLevel isolationLevel = new IsolationLevel();
040:
041: private boolean commmitted = false;
042: private boolean newTransaction = false;
043:
044: public JtaTransaction(UserTransaction utx, DataSource ds,
045: int isolationLevel) throws TransactionException {
046: // Check parameters
047: userTransaction = utx;
048: dataSource = ds;
049: if (userTransaction == null) {
050: throw new TransactionException(
051: "JtaTransaction initialization failed. UserTransaction was null.");
052: }
053: if (dataSource == null) {
054: throw new TransactionException(
055: "JtaTransaction initialization failed. DataSource was null.");
056: }
057: this .isolationLevel.setIsolationLevel(isolationLevel);
058: }
059:
060: private void init() throws TransactionException, SQLException {
061: // Start JTA Transaction
062: try {
063: newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
064: if (newTransaction) {
065: userTransaction.begin();
066: }
067: } catch (Exception e) {
068: throw new TransactionException(
069: "JtaTransaction could not start transaction. Cause: ",
070: e);
071: }
072:
073: // Open JDBC Connection
074: connection = dataSource.getConnection();
075: if (connection == null) {
076: throw new TransactionException(
077: "JtaTransaction could not start transaction. Cause: The DataSource returned a null connection.");
078: }
079: // Isolation Level
080: isolationLevel.applyIsolationLevel(connection);
081: // AutoCommit
082: if (connection.getAutoCommit()) {
083: connection.setAutoCommit(false);
084: }
085: // Debug
086: if (connectionLog.isDebugEnabled()) {
087: connection = ConnectionLogProxy.newInstance(connection);
088: }
089: }
090:
091: public void commit() throws SQLException, TransactionException {
092: if (connection != null) {
093: if (commmitted) {
094: throw new TransactionException(
095: "JtaTransaction could not commit because this transaction has already been committed.");
096: }
097: try {
098: if (newTransaction) {
099: userTransaction.commit();
100: }
101: } catch (Exception e) {
102: throw new TransactionException(
103: "JtaTransaction could not commit. Cause: ", e);
104: }
105: commmitted = true;
106: }
107: }
108:
109: public void rollback() throws SQLException, TransactionException {
110: if (connection != null) {
111: if (!commmitted) {
112: try {
113: if (userTransaction != null) {
114: if (newTransaction) {
115: userTransaction.rollback();
116: } else {
117: userTransaction.setRollbackOnly();
118: }
119: }
120: } catch (Exception e) {
121: throw new TransactionException(
122: "JtaTransaction could not rollback. Cause: ",
123: e);
124: }
125: }
126: }
127: }
128:
129: public void close() throws SQLException, TransactionException {
130: if (connection != null) {
131: try {
132: isolationLevel.restoreIsolationLevel(connection);
133: } finally {
134: connection.close();
135: connection = null;
136: }
137: }
138: }
139:
140: public Connection getConnection() throws SQLException,
141: TransactionException {
142: if (connection == null) {
143: init();
144: }
145: return connection;
146: }
147:
148: }
|