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 public SpringManagedTransaction(DataSource dataSource) {
57 notNull(dataSource, "No DataSource specified");
58 this.dataSource = dataSource;
59 }
60
61
62
63
64 @Override
65 public Connection getConnection() throws SQLException {
66 if (this.connection == null) {
67 openConnection();
68 }
69 return this.connection;
70 }
71
72
73
74
75
76
77
78
79 private void openConnection() throws SQLException {
80 this.connection = DataSourceUtils.getConnection(this.dataSource);
81 this.autoCommit = this.connection.getAutoCommit();
82 this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);
83
84 LOGGER.debug(() -> "JDBC Connection [" + this.connection + "] will"
85 + (this.isConnectionTransactional ? " " : " not ") + "be managed by Spring");
86 }
87
88
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
100
101
102 @Override
103 public void rollback() throws SQLException {
104 if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
105 LOGGER.debug(() -> "Rolling back JDBC Connection [" + this.connection + "]");
106 this.connection.rollback();
107 }
108 }
109
110
111
112
113 @Override
114 public void close() throws SQLException {
115 DataSourceUtils.releaseConnection(this.connection, this.dataSource);
116 }
117
118
119
120
121 @Override
122 public Integer getTimeout() throws SQLException {
123 ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
124 if (holder != null && holder.hasTimeout()) {
125 return holder.getTimeToLiveInSeconds();
126 }
127 return null;
128 }
129
130 }