1
1
/*
2
- * Copyright 2002-2022 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
35
35
import org .springframework .util .Assert ;
36
36
37
37
/**
38
- * {@link org.springframework.transaction.PlatformTransactionManager}
39
- * implementation for a single JDBC {@link javax.sql.DataSource}. This class is
40
- * capable of working in any environment with any JDBC driver, as long as the setup
41
- * uses a {@code javax.sql.DataSource} as its {@code Connection} factory mechanism.
42
- * Binds a JDBC Connection from the specified DataSource to the current thread,
43
- * potentially allowing for one thread-bound Connection per DataSource.
38
+ * {@link org.springframework.transaction.PlatformTransactionManager} implementation
39
+ * for a single JDBC {@link javax.sql.DataSource}. This class is capable of working
40
+ * in any environment with any JDBC driver, as long as the setup uses a
41
+ * {@code javax.sql.DataSource} as its {@code Connection} factory mechanism.
42
+ * Binds a JDBC {@code Connection} from the specified {@code DataSource} to the
43
+ * current thread, potentially allowing for one thread-bound {@code Connection}
44
+ * per {@code DataSource}.
44
45
*
45
- * <p><b>Note: The DataSource that this transaction manager operates on needs
46
- * to return independent Connections .</b> The Connections may come from a pool
47
- * (the typical case), but the DataSource must not return thread-scoped /
48
- * request- scoped Connections or the like . This transaction manager will
49
- * associate Connections with thread-bound transactions itself , according
50
- * to the specified propagation behavior. It assumes that a separate,
51
- * independent Connection can be obtained even during an ongoing transaction.
46
+ * <p><b>Note: The {@code DataSource} that this transaction manager operates on
47
+ * needs to return independent {@code Connection}s .</b> The {@code Connection}s
48
+ * typically come from a connection pool but the {@code DataSource} must not return
49
+ * specifically scoped or constrained {@code Connection}s . This transaction manager
50
+ * will associate {@code Connection}s with thread-bound transactions, according
51
+ * to the specified propagation behavior. It assumes that a separate, independent
52
+ * {@code Connection} can be obtained even during an ongoing transaction.
52
53
*
53
- * <p>Application code is required to retrieve the JDBC Connection via
54
+ * <p>Application code is required to retrieve the JDBC {@code Connection} via
54
55
* {@link DataSourceUtils#getConnection(DataSource)} instead of a standard
55
- * Jakarta EE-style {@link DataSource#getConnection()} call. Spring classes such as
56
+ * EE-style {@link DataSource#getConnection()} call. Spring classes such as
56
57
* {@link org.springframework.jdbc.core.JdbcTemplate} use this strategy implicitly.
57
58
* If not used in combination with this transaction manager, the
58
59
* {@link DataSourceUtils} lookup strategy behaves exactly like the native
59
- * DataSource lookup; it can thus be used in a portable fashion.
60
+ * {@code DataSource} lookup; it can thus be used in a portable fashion.
60
61
*
61
62
* <p>Alternatively, you can allow application code to work with the standard
62
- * Jakarta EE-style lookup pattern {@link DataSource#getConnection()}, for example for
63
- * legacy code that is not aware of Spring at all. In that case, define a
64
- * {@link TransactionAwareDataSourceProxy} for your target DataSource, and pass
65
- * that proxy DataSource to your DAOs, which will automatically participate in
66
- * Spring-managed transactions when accessing it.
63
+ * EE-style lookup pattern {@link DataSource#getConnection()}, for example
64
+ * for legacy code that is not aware of Spring at all. In that case, define a
65
+ * {@link TransactionAwareDataSourceProxy} for your target {@code DataSource},
66
+ * and pass that proxy {@code DataSource} to your DAOs which will automatically
67
+ * participate in Spring-managed transactions when accessing it.
67
68
*
68
69
* <p>Supports custom isolation levels, and timeouts which get applied as
69
70
* appropriate JDBC statement timeouts. To support the latter, application code
70
71
* must either use {@link org.springframework.jdbc.core.JdbcTemplate}, call
71
- * {@link DataSourceUtils#applyTransactionTimeout} for each created JDBC Statement,
72
- * or go through a {@link TransactionAwareDataSourceProxy} which will create
73
- * timeout-aware JDBC Connections and Statements automatically.
72
+ * {@link DataSourceUtils#applyTransactionTimeout} for each created JDBC
73
+ * {@code Statement}, or go through a {@link TransactionAwareDataSourceProxy}
74
+ * which will create timeout-aware JDBC {@code Connection}s and {@code Statement}s
75
+ * automatically.
74
76
*
75
77
* <p>Consider defining a {@link LazyConnectionDataSourceProxy} for your target
76
- * DataSource, pointing both this transaction manager and your DAOs to it.
78
+ * {@code DataSource} , pointing both this transaction manager and your DAOs to it.
77
79
* This will lead to optimized handling of "empty" transactions, i.e. of transactions
78
- * without any JDBC statements executed. A LazyConnectionDataSourceProxy will not fetch
79
- * an actual JDBC Connection from the target DataSource until a Statement gets executed,
80
- * lazily applying the specified transaction settings to the target Connection.
80
+ * without any JDBC statements executed. A {@code LazyConnectionDataSourceProxy} will
81
+ * not fetch an actual JDBC {@code Connection} from the target {@code DataSource}
82
+ * until a {@code Statement} gets executed, lazily applying the specified transaction
83
+ * settings to the target {@code Connection}.
81
84
*
82
85
* <p>This transaction manager supports nested transactions via the JDBC 3.0
83
86
* {@link java.sql.Savepoint} mechanism. The
88
91
* <p>This transaction manager can be used as a replacement for the
89
92
* {@link org.springframework.transaction.jta.JtaTransactionManager} in the single
90
93
* resource case, as it does not require a container that supports JTA, typically
91
- * in combination with a locally defined JDBC DataSource (e.g. an Apache Commons
92
- * DBCP connection pool). Switching between this local strategy and a JTA
93
- * environment is just a matter of configuration!
94
+ * in combination with a locally defined JDBC {@code DataSource} (e.g. a Hikari
95
+ * connection pool). Switching between this local strategy and a JTA environment
96
+ * is just a matter of configuration!
94
97
*
95
98
* <p>As of 4.3.4, this transaction manager triggers flush callbacks on registered
96
99
* transaction synchronizations (if synchronization is generally active), assuming
112
115
* @see TransactionAwareDataSourceProxy
113
116
* @see LazyConnectionDataSourceProxy
114
117
* @see org.springframework.jdbc.core.JdbcTemplate
118
+ * @see org.springframework.jdbc.support.JdbcTransactionManager
115
119
*/
116
120
@ SuppressWarnings ("serial" )
117
121
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
@@ -124,16 +128,16 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
124
128
125
129
126
130
/**
127
- * Create a new DataSourceTransactionManager instance.
128
- * A DataSource has to be set to be able to use it.
131
+ * Create a new {@code DataSourceTransactionManager} instance.
132
+ * A {@code DataSource} has to be set to be able to use it.
129
133
* @see #setDataSource
130
134
*/
131
135
public DataSourceTransactionManager () {
132
136
setNestedTransactionAllowed (true );
133
137
}
134
138
135
139
/**
136
- * Create a new DataSourceTransactionManager instance.
140
+ * Create a new {@code DataSourceTransactionManager} instance.
137
141
* @param dataSource the JDBC DataSource to manage transactions for
138
142
*/
139
143
public DataSourceTransactionManager (DataSource dataSource ) {
@@ -144,22 +148,22 @@ public DataSourceTransactionManager(DataSource dataSource) {
144
148
145
149
146
150
/**
147
- * Set the JDBC DataSource that this instance should manage transactions for.
148
- * <p>This will typically be a locally defined DataSource, for example an
149
- * Apache Commons DBCP connection pool. Alternatively, you can also drive
150
- * transactions for a non-XA J2EE DataSource fetched from JNDI. For an XA
151
- * DataSource, use JtaTransactionManager.
152
- * <p>The DataSource specified here should be the target DataSource to manage
153
- * transactions for, not a TransactionAwareDataSourceProxy. Only data access
154
- * code may work with TransactionAwareDataSourceProxy, while the transaction
155
- * manager needs to work on the underlying target DataSource. If there's
156
- * nevertheless a TransactionAwareDataSourceProxy passed in, it will be
157
- * unwrapped to extract its target DataSource.
158
- * <p><b>The DataSource passed in here needs to return independent Connections.</b>
159
- * The Connections may come from a pool (the typical case), but the DataSource
160
- * must not return thread-scoped / request-scoped Connections or the like.
161
- * @see TransactionAwareDataSourceProxy
162
- * @see org.springframework.transaction.jta.JtaTransactionManager
151
+ * Set the JDBC {@code DataSource} that this instance should manage transactions for.
152
+ * <p>This will typically be a locally defined {@code DataSource} , for example a
153
+ * Hikari connection pool. Alternatively, you can also manage transactions for a
154
+ * non-XA {@code DataSource} fetched from JNDI. For an XA {@code DataSource},
155
+ * use {@link org.springframework.transaction.jta. JtaTransactionManager} instead .
156
+ * <p>The {@code DataSource} specified here should be the target {@code DataSource}
157
+ * to manage transactions for, not a {@link TransactionAwareDataSourceProxy}.
158
+ * Only data access code may work with {@code TransactionAwareDataSourceProxy} while
159
+ * the transaction manager needs to work on the underlying target {@code DataSource}.
160
+ * If there is nevertheless a {@code TransactionAwareDataSourceProxy} passed in,
161
+ * it will be unwrapped to extract its target {@code DataSource} .
162
+ * <p><b>The {@code DataSource} passed in here needs to return independent
163
+ * {@code Connection}s.</b> The {@code Connection}s typically come from a
164
+ * connection pool but the {@code DataSource} must not return specifically
165
+ * scoped or constrained {@code Connection}s, just possibly lazily fetched.
166
+ * @see LazyConnectionDataSourceProxy
163
167
*/
164
168
public void setDataSource (@ Nullable DataSource dataSource ) {
165
169
if (dataSource instanceof TransactionAwareDataSourceProxy tadsp ) {
@@ -174,15 +178,15 @@ public void setDataSource(@Nullable DataSource dataSource) {
174
178
}
175
179
176
180
/**
177
- * Return the JDBC DataSource that this instance manages transactions for.
181
+ * Return the JDBC {@code DataSource} that this instance manages transactions for.
178
182
*/
179
183
@ Nullable
180
184
public DataSource getDataSource () {
181
185
return this .dataSource ;
182
186
}
183
187
184
188
/**
185
- * Obtain the DataSource for actual use.
189
+ * Obtain the {@code DataSource} for actual use.
186
190
* @return the DataSource (never {@code null})
187
191
* @throws IllegalStateException in case of no DataSource set
188
192
* @since 5.0
0 commit comments