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