1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.spring.transaction;
17
18 import static org.springframework.util.Assert.notNull;
19
20 import java.sql.Connection;
21 import java.sql.SQLException;
22
23 import javax.sql.DataSource;
24
25 import org.apache.ibatis.transaction.Transaction;
26 import org.mybatis.logging.Logger;
27 import org.mybatis.logging.LoggerFactory;
28 import org.springframework.jdbc.datasource.ConnectionHolder;
29 import org.springframework.jdbc.datasource.DataSourceUtils;
30 import org.springframework.transaction.support.TransactionSynchronizationManager;
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class SpringManagedTransaction implements Transaction {
45
46 private static final Logger LOGGER = LoggerFactory.getLogger(SpringManagedTransaction.class);
47
48 private final DataSource dataSource;
49
50 private Connection connection;
51
52 private boolean isConnectionTransactional;
53
54 private boolean autoCommit;
55
56
57
58
59
60
61
62 public SpringManagedTransaction(DataSource dataSource) {
63 notNull(dataSource, "No DataSource specified");
64 this.dataSource = dataSource;
65 }
66
67 @Override
68 public Connection getConnection() throws SQLException {
69 if (this.connection == null) {
70 openConnection();
71 }
72 return this.connection;
73 }
74
75
76
77
78
79
80
81
82 private void openConnection() throws SQLException {
83 this.connection = DataSourceUtils.getConnection(this.dataSource);
84 this.autoCommit = this.connection.getAutoCommit();
85 this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);
86
87 LOGGER.debug(() -> "JDBC Connection [" + this.connection + "] will"
88 + (this.isConnectionTransactional ? " " : " not ") + "be managed by Spring");
89 }
90
91 @Override
92 public void commit() throws SQLException {
93 if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
94 LOGGER.debug(() -> "Committing JDBC Connection [" + this.connection + "]");
95 this.connection.commit();
96 }
97 }
98
99 @Override
100 public void rollback() throws SQLException {
101 if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
102 LOGGER.debug(() -> "Rolling back JDBC Connection [" + this.connection + "]");
103 this.connection.rollback();
104 }
105 }
106
107 @Override
108 public void close() throws SQLException {
109 DataSourceUtils.releaseConnection(this.connection, this.dataSource);
110 }
111
112 @Override
113 public Integer getTimeout() throws SQLException {
114 var holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
115 if (holder != null && holder.hasTimeout()) {
116 return holder.getTimeToLiveInSeconds();
117 }
118 return null;
119 }
120
121 }