0
# Transaction Management
1
2
Hibernate Core provides comprehensive transaction management capabilities supporting both resource-local transactions and JTA (Jakarta Transaction API) transactions. The framework handles transaction coordination, connection management, and integration with various transaction managers.
3
4
## Capabilities
5
6
### Transaction Interface
7
8
Core interface for managing resource-local transactions.
9
10
```java { .api }
11
/**
12
* Represents a database transaction
13
*/
14
public interface Transaction {
15
/**
16
* Begin the transaction
17
* @throws HibernateException if transaction cannot be started
18
*/
19
void begin();
20
21
/**
22
* Commit the transaction
23
* @throws HibernateException if transaction cannot be committed
24
*/
25
void commit();
26
27
/**
28
* Rollback the transaction
29
* @throws HibernateException if transaction cannot be rolled back
30
*/
31
void rollback();
32
33
/**
34
* Mark the transaction for rollback only
35
*/
36
void setRollbackOnly();
37
38
/**
39
* Check if the transaction is marked for rollback only
40
* @return true if marked for rollback only
41
*/
42
boolean getRollbackOnly();
43
44
/**
45
* Check if the transaction is active
46
* @return true if transaction is active
47
*/
48
boolean isActive();
49
50
/**
51
* Get the transaction status
52
* @return the current transaction status
53
*/
54
TransactionStatus getStatus();
55
56
// Timeout management
57
58
/**
59
* Set the transaction timeout in seconds
60
* @param seconds timeout in seconds
61
*/
62
void setTimeout(int seconds);
63
64
/**
65
* Get the transaction timeout
66
* @return timeout in seconds, or -1 if not set
67
*/
68
int getTimeout();
69
70
// Registration callbacks
71
72
/**
73
* Register a synchronization callback
74
* @param synchronization the synchronization callback
75
*/
76
void registerSynchronization(Synchronization synchronization);
77
}
78
79
/**
80
* Transaction status enumeration
81
*/
82
public enum TransactionStatus {
83
/** Transaction not yet started */
84
NOT_ACTIVE,
85
/** Transaction is active */
86
ACTIVE,
87
/** Transaction has been committed */
88
COMMITTED,
89
/** Transaction has been rolled back */
90
ROLLED_BACK,
91
/** Transaction is marked for rollback only */
92
MARKED_ROLLBACK,
93
/** Transaction is committing */
94
COMMITTING,
95
/** Transaction is rolling back */
96
ROLLING_BACK
97
}
98
```
99
100
### Synchronization Interface
101
102
Callback interface for transaction lifecycle events.
103
104
```java { .api }
105
/**
106
* Transaction synchronization callback
107
*/
108
public interface Synchronization {
109
/**
110
* Called before transaction completion
111
*/
112
void beforeCompletion();
113
114
/**
115
* Called after transaction completion
116
* @param status the completion status
117
*/
118
void afterCompletion(int status);
119
}
120
```
121
122
### Transaction Coordinator
123
124
Service for coordinating transactions across different transaction strategies.
125
126
```java { .api }
127
/**
128
* Contract for coordinating transactions
129
*/
130
public interface TransactionCoordinator {
131
/**
132
* Get the current transaction
133
* @return the current Transaction
134
*/
135
Transaction getCurrentTransaction();
136
137
/**
138
* Begin a new transaction
139
* @return the started Transaction
140
*/
141
Transaction beginTransaction();
142
143
/**
144
* Check if there is an active transaction
145
* @return true if transaction is active
146
*/
147
boolean isActive();
148
149
/**
150
* Get the transaction status
151
* @return current transaction status
152
*/
153
TransactionStatus getTransactionStatus();
154
}
155
```
156
157
### JTA Integration
158
159
Support for JTA transactions in managed environments.
160
161
```java { .api }
162
/**
163
* JTA platform abstraction
164
*/
165
public interface JtaPlatform {
166
/**
167
* Locate the JTA TransactionManager
168
* @return the TransactionManager
169
*/
170
TransactionManager retrieveTransactionManager();
171
172
/**
173
* Locate the JTA UserTransaction
174
* @return the UserTransaction
175
*/
176
UserTransaction retrieveUserTransaction();
177
178
/**
179
* Can we register synchronizations directly with TransactionManager
180
* @return true if direct registration is supported
181
*/
182
boolean canRegisterSynchronization();
183
184
/**
185
* Register a synchronization with the current transaction
186
* @param synchronization the synchronization to register
187
*/
188
void registerSynchronization(Synchronization synchronization);
189
190
/**
191
* Get the current transaction status
192
* @return the transaction status
193
*/
194
int getCurrentStatus();
195
}
196
```
197
198
### Connection Release Modes
199
200
Control when database connections are released.
201
202
```java { .api }
203
/**
204
* Modes for releasing JDBC connections
205
*/
206
public enum ConnectionReleaseMode {
207
/**
208
* Release connections when transaction completes
209
*/
210
ON_CLOSE,
211
212
/**
213
* Release connections after each statement execution
214
*/
215
AFTER_STATEMENT,
216
217
/**
218
* Release connections after each transaction
219
*/
220
AFTER_TRANSACTION,
221
222
/**
223
* Automatically determine release mode
224
*/
225
AUTO
226
}
227
```
228
229
## Usage Examples
230
231
### Basic Transaction Management
232
233
```java
234
import org.hibernate.*;
235
236
// Manual transaction management
237
Session session = sessionFactory.openSession();
238
Transaction tx = null;
239
240
try {
241
tx = session.beginTransaction();
242
243
// Perform database operations
244
User user = new User("john.doe", "John Doe");
245
session.persist(user);
246
247
// Update existing entity
248
User existingUser = session.find(User.class, 123L);
249
existingUser.setEmail("new.email@example.com");
250
251
// Commit transaction
252
tx.commit();
253
254
} catch (Exception e) {
255
// Rollback on error
256
if (tx != null && tx.isActive()) {
257
tx.rollback();
258
}
259
throw e;
260
} finally {
261
session.close();
262
}
263
```
264
265
### Try-with-Resources Pattern
266
267
```java
268
// Automatic resource management
269
try (Session session = sessionFactory.openSession()) {
270
Transaction tx = session.beginTransaction();
271
272
// Database operations
273
List<User> users = session.createQuery("FROM User WHERE active = true", User.class)
274
.getResultList();
275
276
for (User user : users) {
277
user.setLastLoginCheck(LocalDateTime.now());
278
}
279
280
tx.commit();
281
282
} // Session automatically closed
283
```
284
285
### SessionFactory Convenience Methods
286
287
```java
288
// Execute work in a transaction
289
User createdUser = sessionFactory.inTransaction(session -> {
290
User user = new User("jane.doe", "Jane Doe");
291
session.persist(user);
292
return user;
293
});
294
295
// Execute work in a session (manual transaction control)
296
List<Order> orders = sessionFactory.inSession(session -> {
297
Transaction tx = session.beginTransaction();
298
299
List<Order> result = session.createQuery(
300
"FROM Order o WHERE o.status = :status", Order.class)
301
.setParameter("status", OrderStatus.PENDING)
302
.getResultList();
303
304
// Perform bulk update
305
session.createMutationQuery(
306
"UPDATE Order SET processedDate = :date WHERE status = :status")
307
.setParameter("date", LocalDateTime.now())
308
.setParameter("status", OrderStatus.PENDING)
309
.executeUpdate();
310
311
tx.commit();
312
return result;
313
});
314
```
315
316
### Transaction Timeout and Rollback
317
318
```java
319
try (Session session = sessionFactory.openSession()) {
320
Transaction tx = session.beginTransaction();
321
322
// Set transaction timeout (30 seconds)
323
tx.setTimeout(30);
324
325
try {
326
// Long-running operation
327
performBulkDataProcessing(session);
328
329
// Check if we need to rollback due to business logic
330
if (someBusinessCondition) {
331
tx.setRollbackOnly();
332
}
333
334
// Commit if not marked for rollback
335
if (!tx.getRollbackOnly()) {
336
tx.commit();
337
} else {
338
tx.rollback();
339
}
340
341
} catch (Exception e) {
342
tx.rollback();
343
throw e;
344
}
345
}
346
```
347
348
### Synchronization Callbacks
349
350
```java
351
// Custom synchronization for cleanup operations
352
public class AuditSynchronization implements Synchronization {
353
private final String operation;
354
private final Long entityId;
355
356
public AuditSynchronization(String operation, Long entityId) {
357
this.operation = operation;
358
this.entityId = entityId;
359
}
360
361
@Override
362
public void beforeCompletion() {
363
// Prepare audit log entry
364
log.debug("Preparing audit log for {} on entity {}", operation, entityId);
365
}
366
367
@Override
368
public void afterCompletion(int status) {
369
if (status == Status.STATUS_COMMITTED) {
370
// Log successful operation
371
auditLogger.logOperation(operation, entityId, "SUCCESS");
372
} else {
373
// Log failed operation
374
auditLogger.logOperation(operation, entityId, "FAILED");
375
}
376
}
377
}
378
379
// Usage
380
try (Session session = sessionFactory.openSession()) {
381
Transaction tx = session.beginTransaction();
382
383
User user = new User("test.user", "Test User");
384
session.persist(user);
385
386
// Register synchronization
387
tx.registerSynchronization(new AuditSynchronization("CREATE_USER", user.getId()));
388
389
tx.commit();
390
}
391
```
392
393
### Batch Processing with Transaction Management
394
395
```java
396
// Efficient batch processing with periodic commits
397
try (Session session = sessionFactory.openSession()) {
398
Transaction tx = session.beginTransaction();
399
400
int batchSize = 100;
401
int count = 0;
402
403
// Process large dataset
404
try (ScrollableResults<User> results = session.createQuery("FROM User", User.class)
405
.scroll(ScrollMode.FORWARD_ONLY)) {
406
407
while (results.next()) {
408
User user = results.get();
409
410
// Process user
411
user.setProcessedDate(LocalDateTime.now());
412
user.setStatus(UserStatus.PROCESSED);
413
414
// Periodic flush and commit
415
if (++count % batchSize == 0) {
416
session.flush();
417
tx.commit();
418
419
// Start new transaction
420
tx = session.beginTransaction();
421
session.clear(); // Clear first-level cache
422
}
423
}
424
425
// Commit remaining items
426
if (count % batchSize != 0) {
427
tx.commit();
428
}
429
}
430
}
431
```
432
433
### JTA Transaction Integration
434
435
```java
436
// Configuration for JTA transactions
437
@Configuration
438
public class HibernateConfig {
439
440
@Bean
441
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
442
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
443
em.setDataSource(dataSource());
444
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
445
446
Properties props = new Properties();
447
props.setProperty("hibernate.transaction.coordinator_class", "jta");
448
props.setProperty("hibernate.transaction.jta.platform",
449
"org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform");
450
em.setJpaProperties(props);
451
452
return em;
453
}
454
}
455
456
// Using JTA transactions with @Transactional
457
@Service
458
@Transactional
459
public class UserService {
460
461
@PersistenceContext
462
private EntityManager entityManager;
463
464
public User createUser(String username, String name) {
465
// JTA transaction managed by container
466
User user = new User(username, name);
467
entityManager.persist(user);
468
return user;
469
}
470
471
@Transactional(rollbackFor = Exception.class)
472
public void updateUserBatch(List<Long> userIds) {
473
for (Long userId : userIds) {
474
User user = entityManager.find(User.class, userId);
475
if (user != null) {
476
user.setLastUpdated(LocalDateTime.now());
477
}
478
}
479
// Transaction committed automatically
480
}
481
}
482
```
483
484
### Error Handling and Recovery
485
486
```java
487
public class TransactionalService {
488
489
private final SessionFactory sessionFactory;
490
private final int maxRetries = 3;
491
492
public void performTransactionalOperation(Long userId) {
493
int attempts = 0;
494
495
while (attempts < maxRetries) {
496
try (Session session = sessionFactory.openSession()) {
497
Transaction tx = session.beginTransaction();
498
499
try {
500
// Perform operation
501
User user = session.find(User.class, userId);
502
if (user == null) {
503
throw new EntityNotFoundException("User not found: " + userId);
504
}
505
506
user.incrementVersion();
507
session.merge(user);
508
509
tx.commit();
510
return; // Success, exit retry loop
511
512
} catch (StaleObjectStateException | OptimisticLockException e) {
513
// Optimistic locking conflict - retry
514
tx.rollback();
515
attempts++;
516
517
if (attempts >= maxRetries) {
518
throw new TransactionRetryException(
519
"Failed after " + maxRetries + " attempts", e);
520
}
521
522
// Wait before retry (exponential backoff)
523
Thread.sleep(100 * attempts);
524
525
} catch (Exception e) {
526
// Other errors - don't retry
527
tx.rollback();
528
throw new TransactionException("Transaction failed", e);
529
}
530
}
531
}
532
}
533
}
534
```
535
536
## Transaction Configuration
537
538
### Hibernate Properties
539
540
```java
541
// Transaction-related configuration properties
542
Properties props = new Properties();
543
544
// Transaction coordinator strategy
545
props.setProperty("hibernate.transaction.coordinator_class", "jdbc"); // or "jta"
546
547
// JTA platform (for JTA transactions)
548
props.setProperty("hibernate.transaction.jta.platform",
549
"org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform");
550
551
// Connection release mode
552
props.setProperty("hibernate.connection.release_mode", "after_transaction");
553
554
// Auto-commit mode (for JDBC transactions)
555
props.setProperty("hibernate.connection.autocommit", "false");
556
557
// Transaction timeout (seconds)
558
props.setProperty("hibernate.transaction.timeout", "300");
559
```
560
561
### Spring Integration
562
563
```java
564
@Configuration
565
@EnableTransactionManagement
566
public class TransactionConfig {
567
568
@Bean
569
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
570
JpaTransactionManager transactionManager = new JpaTransactionManager();
571
transactionManager.setEntityManagerFactory(emf);
572
return transactionManager;
573
}
574
575
@Bean
576
public TransactionTemplate transactionTemplate(PlatformTransactionManager txManager) {
577
TransactionTemplate template = new TransactionTemplate(txManager);
578
template.setTimeout(30); // 30 seconds
579
template.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
580
return template;
581
}
582
}
583
```
584
585
## Transaction Best Practices
586
587
### Performance and Scalability
588
589
- Keep transactions short to minimize lock contention
590
- Use batch processing for bulk operations
591
- Consider connection release modes for long-running processes
592
- Implement proper retry logic for optimistic locking conflicts
593
594
### Error Handling
595
596
- Always handle transaction rollback in exception scenarios
597
- Use appropriate exception types for different error conditions
598
- Implement proper logging for transaction lifecycle events
599
- Consider compensation patterns for distributed transactions
600
601
### Resource Management
602
603
- Use try-with-resources for automatic session cleanup
604
- Properly configure connection pools for transaction load
605
- Monitor transaction duration and identify long-running transactions
606
- Implement transaction timeouts to prevent deadlocks