1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.ibatis.sqlmap.engine.transaction.jta;
17
18 import com.ibatis.common.jdbc.logging.ConnectionLogProxy;
19 import com.ibatis.common.logging.Log;
20 import com.ibatis.common.logging.LogFactory;
21 import com.ibatis.sqlmap.engine.transaction.IsolationLevel;
22 import com.ibatis.sqlmap.engine.transaction.Transaction;
23 import com.ibatis.sqlmap.engine.transaction.TransactionException;
24
25 import java.sql.Connection;
26 import java.sql.SQLException;
27
28 import javax.sql.DataSource;
29 import javax.transaction.Status;
30 import javax.transaction.UserTransaction;
31
32
33
34
35 public class JavaxTransaction implements Transaction {
36
37
38 private static final Log connectionLog = LogFactory.getLog(Connection.class);
39
40
41 private UserTransaction userTransaction;
42
43
44 private DataSource dataSource;
45
46
47 private Connection connection;
48
49
50 private IsolationLevel isolationLevel = new IsolationLevel();
51
52
53 private boolean commmitted = false;
54
55
56 private boolean newTransaction = false;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public JavaxTransaction(UserTransaction utx, DataSource ds, int isolationLevel) throws TransactionException {
72
73 userTransaction = utx;
74 dataSource = ds;
75 if (userTransaction == null) {
76 throw new TransactionException("JtaTransaction initialization failed. UserTransaction was null.");
77 }
78 if (dataSource == null) {
79 throw new TransactionException("JtaTransaction initialization failed. DataSource was null.");
80 }
81 this.isolationLevel.setIsolationLevel(isolationLevel);
82 }
83
84
85
86
87
88
89
90
91
92 private void init() throws TransactionException, SQLException {
93
94 try {
95 newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
96 if (newTransaction) {
97 userTransaction.begin();
98 }
99 } catch (Exception e) {
100 throw new TransactionException("JtaTransaction could not start transaction. Cause: ", e);
101 }
102
103
104 connection = dataSource.getConnection();
105 if (connection == null) {
106 throw new TransactionException(
107 "JtaTransaction could not start transaction. Cause: The DataSource returned a null connection.");
108 }
109
110 isolationLevel.applyIsolationLevel(connection);
111
112 if (connection.getAutoCommit()) {
113 connection.setAutoCommit(false);
114 }
115
116 if (connectionLog.isDebugEnabled()) {
117 connection = ConnectionLogProxy.newInstance(connection);
118 }
119 }
120
121 @Override
122 public void commit() throws SQLException, TransactionException {
123 if (connection != null) {
124 if (commmitted) {
125 throw new TransactionException(
126 "JtaTransaction could not commit because this transaction has already been committed.");
127 }
128 try {
129 if (newTransaction) {
130 userTransaction.commit();
131 }
132 } catch (Exception e) {
133 throw new TransactionException("JtaTransaction could not commit. Cause: ", e);
134 }
135 commmitted = true;
136 }
137 }
138
139 @Override
140 public void rollback() throws SQLException, TransactionException {
141 if (connection != null && !commmitted) {
142 try {
143 if (userTransaction != null) {
144 if (newTransaction) {
145 userTransaction.rollback();
146 } else {
147 userTransaction.setRollbackOnly();
148 }
149 }
150 } catch (Exception e) {
151 throw new TransactionException("JtaTransaction could not rollback. Cause: ", e);
152 }
153 }
154 }
155
156 @Override
157 public void close() throws SQLException, TransactionException {
158 if (connection != null) {
159 try {
160 isolationLevel.restoreIsolationLevel(connection);
161 } finally {
162 connection.close();
163 connection = null;
164 }
165 }
166 }
167
168 @Override
169 public Connection getConnection() throws SQLException, TransactionException {
170 if (connection == null) {
171 init();
172 }
173 return connection;
174 }
175
176 }