0
# Transaction Management
1
2
Clean abstraction over JDBC and managed transactions with support for different transaction factories and isolation levels. MyBatis provides flexible transaction management suitable for both standalone applications and managed environments.
3
4
## Capabilities
5
6
### Transaction Interface
7
8
Core transaction abstraction that handles database connections and transaction lifecycle.
9
10
```java { .api }
11
/**
12
* Database transaction abstraction
13
*/
14
interface Transaction {
15
/** Get the underlying database connection */
16
Connection getConnection() throws SQLException;
17
18
/** Commit the current transaction */
19
void commit() throws SQLException;
20
21
/** Rollback the current transaction */
22
void rollback() throws SQLException;
23
24
/** Close the transaction and release resources */
25
void close() throws SQLException;
26
27
/** Get timeout value for the transaction */
28
Integer getTimeout() throws SQLException;
29
}
30
```
31
32
### TransactionFactory Interface
33
34
Factory interface for creating transaction instances with different strategies.
35
36
```java { .api }
37
/**
38
* Factory for creating transaction instances
39
*/
40
interface TransactionFactory {
41
/** Set configuration properties */
42
void setProperties(Properties props);
43
44
/** Create transaction from existing connection */
45
Transaction newTransaction(Connection conn);
46
47
/** Create transaction from DataSource with isolation level and autocommit setting */
48
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
49
}
50
```
51
52
### JDBC Transaction Management
53
54
Standard JDBC-based transaction implementation for standalone applications.
55
56
#### JdbcTransactionFactory
57
58
Factory for creating JDBC-based transactions.
59
60
```java { .api }
61
/**
62
* Factory for JDBC-based transactions
63
*/
64
class JdbcTransactionFactory implements TransactionFactory {
65
/** Create JDBC transaction factory */
66
public JdbcTransactionFactory();
67
68
/** Set factory properties */
69
public void setProperties(Properties props);
70
71
/** Create transaction from connection */
72
public Transaction newTransaction(Connection conn);
73
74
/** Create transaction from DataSource */
75
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit);
76
}
77
```
78
79
#### JdbcTransaction
80
81
JDBC transaction implementation that manages connection lifecycle and transaction boundaries.
82
83
```java { .api }
84
/**
85
* JDBC-based transaction implementation
86
*/
87
class JdbcTransaction implements Transaction {
88
/** Create JDBC transaction with DataSource */
89
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit);
90
91
/** Create JDBC transaction with existing Connection */
92
public JdbcTransaction(Connection connection);
93
94
/** Get database connection (lazy initialization) */
95
public Connection getConnection() throws SQLException;
96
97
/** Commit transaction if not in autocommit mode */
98
public void commit() throws SQLException;
99
100
/** Rollback transaction if not in autocommit mode */
101
public void rollback() throws SQLException;
102
103
/** Close connection and clean up resources */
104
public void close() throws SQLException;
105
106
/** Get transaction timeout */
107
public Integer getTimeout() throws SQLException;
108
}
109
```
110
111
**Usage Examples:**
112
113
```java
114
// Programmatic JDBC transaction management
115
DataSource dataSource = new HikariDataSource(config);
116
TransactionFactory transactionFactory = new JdbcTransactionFactory();
117
118
// Create transaction with specific isolation level
119
Transaction transaction = transactionFactory.newTransaction(
120
dataSource,
121
TransactionIsolationLevel.READ_COMMITTED,
122
false // autoCommit = false
123
);
124
125
try {
126
Connection conn = transaction.getConnection();
127
128
// Perform database operations
129
PreparedStatement stmt = conn.prepareStatement("INSERT INTO users (name) VALUES (?)");
130
stmt.setString(1, "John Doe");
131
stmt.executeUpdate();
132
133
// Commit transaction
134
transaction.commit();
135
} catch (SQLException e) {
136
// Rollback on error
137
transaction.rollback();
138
throw e;
139
} finally {
140
transaction.close();
141
}
142
```
143
144
### Managed Transaction Management
145
146
Container-managed transaction implementation for JEE environments where transaction management is handled externally.
147
148
#### ManagedTransactionFactory
149
150
Factory for creating managed transactions that delegate transaction control to the container.
151
152
```java { .api }
153
/**
154
* Factory for container-managed transactions
155
*/
156
class ManagedTransactionFactory implements TransactionFactory {
157
/** Create managed transaction factory */
158
public ManagedTransactionFactory();
159
160
/** Set factory properties */
161
public void setProperties(Properties props);
162
163
/** Create managed transaction from connection */
164
public Transaction newTransaction(Connection conn);
165
166
/** Create managed transaction from DataSource */
167
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit);
168
}
169
```
170
171
#### ManagedTransaction
172
173
Managed transaction implementation that assumes external transaction management.
174
175
```java { .api }
176
/**
177
* Container-managed transaction implementation
178
*/
179
class ManagedTransaction implements Transaction {
180
/** Create managed transaction with DataSource */
181
public ManagedTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean closeConnection);
182
183
/** Create managed transaction with existing Connection */
184
public ManagedTransaction(Connection connection, boolean closeConnection);
185
186
/** Get database connection */
187
public Connection getConnection() throws SQLException;
188
189
/** No-op commit (managed by container) */
190
public void commit() throws SQLException;
191
192
/** No-op rollback (managed by container) */
193
public void rollback() throws SQLException;
194
195
/** Close connection if configured to do so */
196
public void close() throws SQLException;
197
198
/** Get transaction timeout */
199
public Integer getTimeout() throws SQLException;
200
}
201
```
202
203
**Usage Examples:**
204
205
```java
206
// Managed transaction configuration (typically in JEE environment)
207
<environments default="production">
208
<environment id="production">
209
<transactionManager type="MANAGED">
210
<property name="closeConnection" value="false"/>
211
</transactionManager>
212
<dataSource type="JNDI">
213
<property name="data_source" value="java:comp/env/jdbc/MyDataSource"/>
214
</dataSource>
215
</environment>
216
</environments>
217
218
// Using managed transactions with Spring
219
@Transactional
220
@Service
221
public class UserService {
222
private final UserMapper userMapper;
223
224
public UserService(UserMapper userMapper) {
225
this.userMapper = userMapper;
226
}
227
228
@Transactional(isolation = Isolation.READ_COMMITTED)
229
public void createUser(User user) {
230
// MyBatis will participate in Spring's transaction
231
userMapper.insert(user);
232
// Transaction managed by Spring
233
}
234
}
235
```
236
237
### Transaction Isolation Levels
238
239
Enumeration of standard transaction isolation levels with their corresponding JDBC constants.
240
241
```java { .api }
242
/**
243
* Transaction isolation levels
244
*/
245
enum TransactionIsolationLevel {
246
/** No transaction isolation */
247
NONE(Connection.TRANSACTION_NONE),
248
249
/** Read uncommitted isolation level */
250
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
251
252
/** Read committed isolation level */
253
READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
254
255
/** Repeatable read isolation level */
256
REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
257
258
/** Serializable isolation level */
259
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);
260
261
/** Get JDBC isolation level constant */
262
public int getLevel();
263
}
264
```
265
266
**Usage Examples:**
267
268
```java
269
// Configure different isolation levels per operation
270
public interface OrderMapper {
271
// Read operations with lower isolation for better performance
272
@Select("SELECT * FROM orders WHERE id = #{id}")
273
@Options(isolation = IsolationLevel.READ_COMMITTED)
274
Order findById(@Param("id") Long id);
275
276
// Write operations with higher isolation for consistency
277
@Insert("INSERT INTO orders (customer_id, total) VALUES (#{customerId}, #{total})")
278
@Options(isolation = IsolationLevel.SERIALIZABLE)
279
int insert(Order order);
280
}
281
282
// Programmatic isolation level setting
283
try (SqlSession session = sqlSessionFactory.openSession(TransactionIsolationLevel.REPEATABLE_READ)) {
284
OrderMapper mapper = session.getMapper(OrderMapper.class);
285
Order order = mapper.findById(orderId);
286
287
// Operations within this session use REPEATABLE_READ isolation
288
order.setStatus("PROCESSED");
289
mapper.update(order);
290
291
session.commit();
292
}
293
```
294
295
### Environment Configuration
296
297
Configuration of database environments with transaction management settings.
298
299
```java { .api }
300
/**
301
* Database environment configuration
302
*/
303
class Environment {
304
/** Create environment with ID, transaction factory, and data source */
305
public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource);
306
307
/** Get environment ID */
308
public String getId();
309
310
/** Get transaction factory */
311
public TransactionFactory getTransactionFactory();
312
313
/** Get data source */
314
public DataSource getDataSource();
315
316
/** Environment builder for programmatic configuration */
317
public static class Builder {
318
public Builder(String id);
319
public Builder transactionFactory(TransactionFactory transactionFactory);
320
public Builder dataSource(DataSource dataSource);
321
public Environment build();
322
}
323
}
324
```
325
326
**Usage Examples:**
327
328
```java
329
// Programmatic environment configuration
330
DataSource dataSource = new HikariDataSource(hikariConfig);
331
TransactionFactory transactionFactory = new JdbcTransactionFactory();
332
333
Environment environment = new Environment.Builder("production")
334
.transactionFactory(transactionFactory)
335
.dataSource(dataSource)
336
.build();
337
338
Configuration configuration = new Configuration(environment);
339
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(configuration);
340
341
// XML environment configuration
342
<environments default="development">
343
<environment id="development">
344
<transactionManager type="JDBC">
345
<property name="autoCommit" value="false"/>
346
</transactionManager>
347
<dataSource type="POOLED">
348
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
349
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
350
<property name="username" value="user"/>
351
<property name="password" value="password"/>
352
</dataSource>
353
</environment>
354
355
<environment id="production">
356
<transactionManager type="MANAGED">
357
<property name="closeConnection" value="false"/>
358
</transactionManager>
359
<dataSource type="JNDI">
360
<property name="data_source" value="java:comp/env/jdbc/MyDB"/>
361
</dataSource>
362
</environment>
363
</environments>
364
```
365
366
### Transaction Lifecycle Management
367
368
Understanding transaction boundaries and lifecycle in different scenarios.
369
370
```java
371
// Manual transaction management
372
try (SqlSession session = sqlSessionFactory.openSession(false)) { // autoCommit = false
373
try {
374
UserMapper userMapper = session.getMapper(UserMapper.class);
375
OrderMapper orderMapper = session.getMapper(OrderMapper.class);
376
377
// Multiple operations in single transaction
378
User user = new User("John", "john@example.com");
379
userMapper.insert(user);
380
381
Order order = new Order(user.getId(), new BigDecimal("99.99"));
382
orderMapper.insert(order);
383
384
// Commit all operations together
385
session.commit();
386
} catch (Exception e) {
387
// Rollback on any error
388
session.rollback();
389
throw e;
390
}
391
}
392
393
// Batch operations with transaction management
394
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
395
UserMapper mapper = session.getMapper(UserMapper.class);
396
397
try {
398
// Batch multiple operations
399
for (User user : userList) {
400
mapper.insert(user);
401
}
402
403
// Execute batch and commit
404
List<BatchResult> results = session.flushStatements();
405
session.commit();
406
407
// Process batch results
408
for (BatchResult result : results) {
409
System.out.println("Batch affected " + Arrays.toString(result.getUpdateCounts()) + " rows");
410
}
411
} catch (Exception e) {
412
session.rollback();
413
throw e;
414
}
415
}
416
```
417
418
### Savepoint Support
419
420
Advanced transaction management with savepoints for partial rollbacks.
421
422
```java
423
// Using savepoints for complex transaction management
424
try (SqlSession session = sqlSessionFactory.openSession(false)) {
425
Connection conn = session.getConnection();
426
UserMapper userMapper = session.getMapper(UserMapper.class);
427
OrderMapper orderMapper = session.getMapper(OrderMapper.class);
428
429
try {
430
// Create savepoint before risky operation
431
Savepoint savepoint1 = conn.setSavepoint("beforeUserInsert");
432
433
User user = new User("John", "john@example.com");
434
userMapper.insert(user);
435
436
// Another savepoint
437
Savepoint savepoint2 = conn.setSavepoint("beforeOrderInsert");
438
439
try {
440
Order order = new Order(user.getId(), new BigDecimal("99.99"));
441
orderMapper.insert(order);
442
} catch (Exception e) {
443
// Rollback to savepoint2, keeping user insert
444
conn.rollback(savepoint2);
445
System.out.println("Order insert failed, but user insert preserved");
446
}
447
448
// Commit entire transaction
449
session.commit();
450
} catch (Exception e) {
451
// Full rollback
452
session.rollback();
453
throw e;
454
}
455
}
456
```
457
458
## Types
459
460
```java { .api }
461
/**
462
* Transaction-related exceptions
463
*/
464
class TransactionException extends PersistenceException {
465
public TransactionException(String message);
466
public TransactionException(String message, Throwable cause);
467
}
468
469
/**
470
* Transaction manager types for XML configuration
471
*/
472
enum TransactionManagerType {
473
/** JDBC transaction manager */
474
JDBC("JDBC"),
475
476
/** Managed transaction manager */
477
MANAGED("MANAGED");
478
479
public String getValue();
480
}
481
482
/**
483
* Transaction isolation annotation for method-level configuration
484
*/
485
@interface Transactional {
486
/** Transaction isolation level */
487
TransactionIsolationLevel isolation() default TransactionIsolationLevel.READ_COMMITTED;
488
489
/** Transaction propagation behavior */
490
Propagation propagation() default Propagation.REQUIRED;
491
492
/** Transaction timeout in seconds */
493
int timeout() default -1;
494
495
/** Read-only transaction hint */
496
boolean readOnly() default false;
497
}
498
```