or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

exception-handling.mdhibernate-integration.mdindex.mdjpa-integration.mdpersistence-context.mdtransaction-management.md

transaction-management.mddocs/

0

# Transaction Management

1

2

Spring ORM provides platform-agnostic transaction management with support for declarative transactions, programmatic transaction control, resource synchronization, and integration with various ORM frameworks. The transaction management infrastructure ensures ACID properties while providing flexibility across different data access technologies.

3

4

## Capabilities

5

6

### Platform Transaction Management

7

8

Core transaction management abstraction that provides consistent transaction semantics across different ORM frameworks and data access technologies.

9

10

```java { .api }

11

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

12

public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

13

public final void commit(TransactionStatus status) throws TransactionException;

14

public final void rollback(TransactionStatus status) throws TransactionException;

15

16

// Template methods for subclass implementation

17

protected abstract Object doGetTransaction() throws TransactionException;

18

protected abstract void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException;

19

protected abstract void doCommit(DefaultTransactionStatus status) throws TransactionException;

20

protected abstract void doRollback(DefaultTransactionStatus status) throws TransactionException;

21

22

// Configuration methods

23

public void setTransactionSynchronization(int transactionSynchronization);

24

public void setDefaultTimeout(int defaultTimeout);

25

public void setNestedTransactionAllowed(boolean nestedTransactionAllowed);

26

public void setValidateExistingTransaction(boolean validateExistingTransaction);

27

public void setGlobalRollbackOnParticipationFailure(boolean globalRollbackOnParticipationFailure);

28

public void setFailEarlyOnGlobalRollbackOnly(boolean failEarlyOnGlobalRollbackOnly);

29

public void setRollbackOnCommitFailure(boolean rollbackOnCommitFailure);

30

}

31

32

public interface ResourceTransactionManager extends PlatformTransactionManager {

33

Object getResourceFactory();

34

}

35

```

36

37

#### Usage Example

38

39

```java

40

@Configuration

41

@EnableTransactionManagement

42

public class TransactionConfig {

43

44

@Bean

45

public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

46

JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory);

47

48

// Configure transaction manager behavior

49

txManager.setDefaultTimeout(30); // 30 seconds default timeout

50

txManager.setNestedTransactionAllowed(true);

51

txManager.setValidateExistingTransaction(true);

52

txManager.setGlobalRollbackOnParticipationFailure(true);

53

54

return txManager;

55

}

56

}

57

58

@Service

59

@Transactional

60

public class BusinessService {

61

62

@Autowired

63

private PlatformTransactionManager transactionManager;

64

65

// Declarative transaction management

66

@Transactional(timeout = 60, rollbackFor = Exception.class)

67

public void performComplexOperation() {

68

// Business logic automatically runs in transaction

69

}

70

71

// Programmatic transaction management

72

public void performProgrammaticTransaction() {

73

TransactionDefinition def = new DefaultTransactionDefinition();

74

TransactionStatus status = transactionManager.getTransaction(def);

75

76

try {

77

// Perform business operations

78

doBusinessLogic();

79

transactionManager.commit(status);

80

} catch (Exception ex) {

81

transactionManager.rollback(status);

82

throw ex;

83

}

84

}

85

}

86

```

87

88

### JPA Transaction Management

89

90

Specialized transaction manager for JPA that manages EntityManager lifecycle, resource synchronization, and JPA-specific transaction semantics.

91

92

```java { .api }

93

public class JpaTransactionManager extends AbstractPlatformTransactionManager

94

implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {

95

public JpaTransactionManager();

96

public JpaTransactionManager(EntityManagerFactory emf);

97

98

public void setEntityManagerFactory(EntityManagerFactory emf);

99

public EntityManagerFactory getEntityManagerFactory();

100

public void setPersistenceUnitName(String persistenceUnitName);

101

public void setJpaProperties(Properties jpaProperties);

102

public void setDataSource(DataSource dataSource);

103

public void setJpaDialect(JpaDialect jpaDialect);

104

public void setEntityManagerInitializer(Consumer<EntityManager> entityManagerInitializer);

105

106

// ResourceTransactionManager implementation

107

public Object getResourceFactory();

108

}

109

```

110

111

#### Usage Example

112

113

```java

114

@Configuration

115

@EnableTransactionManagement

116

@EnableJpaRepositories(basePackages = "com.example.repository")

117

public class JpaTransactionConfig {

118

119

@Bean

120

public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

121

JpaTransactionManager txManager = new JpaTransactionManager();

122

txManager.setEntityManagerFactory(entityManagerFactory);

123

124

// Optional: Set DataSource for connection-level synchronization

125

txManager.setDataSource(dataSource());

126

127

// Optional: Configure JPA-specific properties

128

Properties jpaProperties = new Properties();

129

jpaProperties.setProperty("javax.persistence.lock.timeout", "5000");

130

txManager.setJpaProperties(jpaProperties);

131

132

// Optional: Set custom JPA dialect

133

txManager.setJpaDialect(new HibernateJpaDialect());

134

135

// Optional: Custom EntityManager initialization

136

txManager.setEntityManagerInitializer(em -> {

137

em.setProperty("org.hibernate.readOnly", true);

138

});

139

140

return txManager;

141

}

142

143

@Bean

144

public DataSource dataSource() {

145

HikariDataSource dataSource = new HikariDataSource();

146

dataSource.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");

147

dataSource.setUsername("user");

148

dataSource.setPassword("password");

149

return dataSource;

150

}

151

}

152

153

@Service

154

@Transactional

155

public class UserService {

156

157

@PersistenceContext

158

private EntityManager entityManager;

159

160

@Transactional(propagation = Propagation.REQUIRED)

161

public void createUser(User user) {

162

entityManager.persist(user);

163

// Transaction commits automatically

164

}

165

166

@Transactional(propagation = Propagation.REQUIRES_NEW)

167

public void logAuditEvent(String action, String details) {

168

AuditEvent event = new AuditEvent();

169

event.setAction(action);

170

event.setDetails(details);

171

event.setTimestamp(Instant.now());

172

entityManager.persist(event);

173

// Runs in separate transaction

174

}

175

176

@Transactional(readOnly = true, timeout = 30)

177

public List<User> findActiveUsers() {

178

return entityManager.createQuery(

179

"SELECT u FROM User u WHERE u.active = true",

180

User.class

181

).getResultList();

182

}

183

}

184

```

185

186

### Hibernate Transaction Management

187

188

Specialized transaction manager for Hibernate that manages Session lifecycle, resource synchronization, and Hibernate-specific transaction semantics.

189

190

```java { .api }

191

public class HibernateTransactionManager extends AbstractPlatformTransactionManager

192

implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {

193

public HibernateTransactionManager();

194

public HibernateTransactionManager(SessionFactory sessionFactory);

195

196

public void setSessionFactory(SessionFactory sessionFactory);

197

public SessionFactory getSessionFactory();

198

public void setDataSource(DataSource dataSource);

199

public void setHibernateProperties(Properties hibernateProperties);

200

public void setEntityInterceptor(Interceptor entityInterceptor);

201

public void setJtaTimeout(int jtaTimeout);

202

203

// ResourceTransactionManager implementation

204

public Object getResourceFactory();

205

}

206

```

207

208

#### Usage Example

209

210

```java

211

@Configuration

212

@EnableTransactionManagement

213

public class HibernateTransactionConfig {

214

215

@Bean

216

public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {

217

HibernateTransactionManager txManager = new HibernateTransactionManager();

218

txManager.setSessionFactory(sessionFactory);

219

220

// Optional: Set DataSource for connection-level synchronization

221

txManager.setDataSource(dataSource());

222

223

// Optional: Configure Hibernate-specific properties for transactions

224

Properties hibernateProperties = new Properties();

225

hibernateProperties.setProperty("hibernate.connection.isolation", "2"); // READ_COMMITTED

226

hibernateProperties.setProperty("hibernate.jdbc.batch_size", "25");

227

txManager.setHibernateProperties(hibernateProperties);

228

229

// Optional: Set entity interceptor for transaction-scoped sessions

230

txManager.setEntityInterceptor(new AuditInterceptor());

231

232

return txManager;

233

}

234

}

235

236

@Service

237

@Transactional

238

public class ProductService {

239

240

@Autowired

241

private SessionFactory sessionFactory;

242

243

@Transactional(isolation = Isolation.READ_COMMITTED)

244

public void updateProductInventory(Long productId, int quantity) {

245

Session session = sessionFactory.getCurrentSession();

246

247

Product product = session.get(Product.class, productId, LockMode.PESSIMISTIC_WRITE);

248

if (product != null) {

249

product.setInventoryCount(product.getInventoryCount() + quantity);

250

session.update(product);

251

}

252

}

253

254

@Transactional(propagation = Propagation.NESTED)

255

public void processOrderItems(List<OrderItem> items) {

256

Session session = sessionFactory.getCurrentSession();

257

258

for (OrderItem item : items) {

259

try {

260

updateProductInventory(item.getProductId(), -item.getQuantity());

261

session.save(item);

262

} catch (Exception ex) {

263

// Nested transaction can rollback independently

264

log.warn("Failed to process item: " + item.getProductId(), ex);

265

throw ex;

266

}

267

}

268

}

269

}

270

```

271

272

### Transaction Synchronization

273

274

Infrastructure for registering callbacks that participate in Spring transaction lifecycle, enabling custom resource management and cleanup.

275

276

```java { .api }

277

public interface TransactionSynchronization {

278

int STATUS_COMMITTED = 0;

279

int STATUS_ROLLED_BACK = 1;

280

int STATUS_UNKNOWN = 2;

281

282

default void suspend();

283

default void resume();

284

default void flush();

285

default void beforeCommit(boolean readOnly);

286

default void beforeCompletion();

287

default void afterCommit();

288

default void afterCompletion(int status);

289

}

290

291

public abstract class TransactionSynchronizationManager {

292

public static Map<Object, Object> getResourceMap();

293

public static boolean hasResource(Object key);

294

public static Object getResource(Object key);

295

public static void bindResource(Object key, Object value) throws IllegalStateException;

296

public static Object unbindResource(Object key) throws IllegalStateException;

297

public static Object unbindResourceIfPossible(Object key);

298

299

public static boolean isSynchronizationActive();

300

public static void initSynchronization() throws IllegalStateException;

301

public static void registerSynchronization(TransactionSynchronization synchronization) throws IllegalStateException;

302

public static List<TransactionSynchronization> getSynchronizations() throws IllegalStateException;

303

public static void clearSynchronization() throws IllegalStateException;

304

305

public static void setCurrentTransactionName(String name);

306

public static String getCurrentTransactionName();

307

public static void setCurrentTransactionReadOnly(boolean readOnly);

308

public static boolean isCurrentTransactionReadOnly();

309

public static void setCurrentTransactionIsolationLevel(Integer isolationLevel);

310

public static Integer getCurrentTransactionIsolationLevel();

311

public static void setActualTransactionActive(boolean active);

312

public static boolean isActualTransactionActive();

313

}

314

```

315

316

#### Usage Example

317

318

```java

319

@Component

320

public class CustomResourceManager {

321

322

private static final Object RESOURCE_KEY = new Object();

323

324

@EventListener

325

public void handleTransactionBegin(TransactionBeginEvent event) {

326

if (TransactionSynchronizationManager.isSynchronizationActive()) {

327

// Register custom synchronization

328

TransactionSynchronizationManager.registerSynchronization(

329

new CustomTransactionSynchronization()

330

);

331

332

// Bind custom resource to transaction

333

CustomResource resource = new CustomResource();

334

TransactionSynchronizationManager.bindResource(RESOURCE_KEY, resource);

335

}

336

}

337

338

private static class CustomTransactionSynchronization implements TransactionSynchronization {

339

340

@Override

341

public void beforeCommit(boolean readOnly) {

342

if (!readOnly) {

343

CustomResource resource = (CustomResource)

344

TransactionSynchronizationManager.getResource(RESOURCE_KEY);

345

if (resource != null) {

346

resource.prepareForCommit();

347

}

348

}

349

}

350

351

@Override

352

public void afterCommit() {

353

CustomResource resource = (CustomResource)

354

TransactionSynchronizationManager.getResource(RESOURCE_KEY);

355

if (resource != null) {

356

resource.afterCommit();

357

}

358

}

359

360

@Override

361

public void afterCompletion(int status) {

362

try {

363

CustomResource resource = (CustomResource)

364

TransactionSynchronizationManager.unbindResourceIfPossible(RESOURCE_KEY);

365

if (resource != null) {

366

if (status == STATUS_COMMITTED) {

367

resource.cleanup();

368

} else {

369

resource.rollback();

370

}

371

}

372

} finally {

373

// Ensure cleanup happens regardless

374

}

375

}

376

}

377

}

378

```

379

380

### Declarative Transaction Configuration

381

382

Annotation-driven transaction management configuration with support for customization and various transaction managers.

383

384

```java { .api }

385

@Target(ElementType.TYPE)

386

@Retention(RetentionPolicy.RUNTIME)

387

@Documented

388

@Import(TransactionManagementConfigurationSelector.class)

389

public @interface EnableTransactionManagement {

390

boolean proxyTargetClass() default false;

391

AdviceMode mode() default AdviceMode.PROXY;

392

int order() default Ordered.LOWEST_PRECEDENCE;

393

}

394

395

@Target({ElementType.TYPE, ElementType.METHOD})

396

@Retention(RetentionPolicy.RUNTIME)

397

@Inherited

398

@Documented

399

public @interface Transactional {

400

String value() default "";

401

String transactionManager() default "";

402

Propagation propagation() default Propagation.REQUIRED;

403

Isolation isolation() default Isolation.DEFAULT;

404

int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

405

boolean readOnly() default false;

406

Class<? extends Throwable>[] rollbackFor() default {};

407

String[] rollbackForClassName() default {};

408

Class<? extends Throwable>[] noRollbackFor() default {};

409

String[] noRollbackForClassName() default {};

410

}

411

412

public enum Propagation {

413

REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

414

SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

415

MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

416

REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

417

NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

418

NEVER(TransactionDefinition.PROPAGATION_NEVER),

419

NESTED(TransactionDefinition.PROPAGATION_NESTED);

420

}

421

422

public enum Isolation {

423

DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),

424

READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),

425

READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),

426

REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),

427

SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);

428

}

429

```

430

431

#### Usage Example

432

433

```java

434

@Configuration

435

@EnableTransactionManagement(

436

proxyTargetClass = true, // Use CGLIB proxies

437

mode = AdviceMode.PROXY, // Use proxy-based AOP

438

order = Ordered.LOWEST_PRECEDENCE // Transaction advice order

439

)

440

public class TransactionManagementConfig {

441

442

@Bean

443

public TransactionAttributeSource transactionAttributeSource() {

444

AnnotationTransactionAttributeSource source = new AnnotationTransactionAttributeSource();

445

return source;

446

}

447

448

@Bean

449

public TransactionInterceptor transactionInterceptor(

450

PlatformTransactionManager transactionManager,

451

TransactionAttributeSource transactionAttributeSource) {

452

TransactionInterceptor interceptor = new TransactionInterceptor();

453

interceptor.setTransactionManager(transactionManager);

454

interceptor.setTransactionAttributeSource(transactionAttributeSource);

455

return interceptor;

456

}

457

}

458

459

@Service

460

public class OrderService {

461

462

// Method-level transaction with specific settings

463

@Transactional(

464

propagation = Propagation.REQUIRED,

465

isolation = Isolation.READ_COMMITTED,

466

timeout = 30,

467

rollbackFor = {BusinessException.class, DataIntegrityViolationException.class},

468

noRollbackFor = {ValidationException.class}

469

)

470

public void processOrder(Order order) {

471

validateOrder(order);

472

saveOrder(order);

473

updateInventory(order.getItems());

474

sendNotification(order);

475

}

476

477

// Read-only transaction for queries

478

@Transactional(readOnly = true, timeout = 15)

479

public List<Order> findOrdersByCustomer(Long customerId) {

480

return orderRepository.findByCustomerId(customerId);

481

}

482

483

// Requires new transaction (always runs in separate transaction)

484

@Transactional(propagation = Propagation.REQUIRES_NEW)

485

public void auditOrderOperation(String operation, Long orderId) {

486

AuditLog log = new AuditLog();

487

log.setOperation(operation);

488

log.setEntityId(orderId);

489

log.setTimestamp(Instant.now());

490

auditRepository.save(log);

491

}

492

}

493

494

// Class-level transaction settings (inherited by all methods)

495

@Service

496

@Transactional(

497

transactionManager = "orderTransactionManager", // Specific transaction manager

498

propagation = Propagation.REQUIRED,

499

isolation = Isolation.READ_COMMITTED,

500

timeout = 30

501

)

502

public class InventoryService {

503

504

// Inherits class-level transaction settings

505

public void updateStock(Long productId, int quantity) {

506

// Business logic

507

}

508

509

// Override class-level settings for this method

510

@Transactional(

511

propagation = Propagation.REQUIRES_NEW,

512

isolation = Isolation.SERIALIZABLE

513

)

514

public void criticalStockUpdate(Long productId, int quantity) {

515

// Critical business logic requiring separate transaction

516

}

517

518

// Non-transactional method

519

@Transactional(propagation = Propagation.NOT_SUPPORTED)

520

public void generateReport() {

521

// Report generation doesn't need transaction

522

}

523

}

524

```

525

526

### Transaction Definition and Status

527

528

Core interfaces and classes that define transaction characteristics and provide runtime transaction information.

529

530

```java { .api }

531

public interface TransactionDefinition {

532

int PROPAGATION_REQUIRED = 0;

533

int PROPAGATION_SUPPORTS = 1;

534

int PROPAGATION_MANDATORY = 2;

535

int PROPAGATION_REQUIRES_NEW = 3;

536

int PROPAGATION_NOT_SUPPORTED = 4;

537

int PROPAGATION_NEVER = 5;

538

int PROPAGATION_NESTED = 6;

539

540

int ISOLATION_DEFAULT = -1;

541

int ISOLATION_READ_UNCOMMITTED = 1;

542

int ISOLATION_READ_COMMITTED = 2;

543

int ISOLATION_REPEATABLE_READ = 4;

544

int ISOLATION_SERIALIZABLE = 8;

545

546

int TIMEOUT_DEFAULT = -1;

547

548

default int getPropagationBehavior();

549

default int getIsolationLevel();

550

default int getTimeout();

551

default boolean isReadOnly();

552

default String getName();

553

}

554

555

public class DefaultTransactionDefinition implements TransactionDefinition, Serializable {

556

public DefaultTransactionDefinition();

557

public DefaultTransactionDefinition(TransactionDefinition other);

558

public DefaultTransactionDefinition(int propagationBehavior);

559

560

public void setPropagationBehavior(int propagationBehavior);

561

public void setIsolationLevel(int isolationLevel);

562

public void setTimeout(int timeout);

563

public void setReadOnly(boolean readOnly);

564

public void setName(String name);

565

}

566

567

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {

568

boolean hasSavepoint();

569

void flush();

570

}

571

572

public interface TransactionExecution {

573

boolean isNewTransaction();

574

void setRollbackOnly();

575

boolean isRollbackOnly();

576

boolean isCompleted();

577

}

578

```

579

580

#### Usage Example

581

582

```java

583

@Service

584

public class PaymentService {

585

586

@Autowired

587

private PlatformTransactionManager transactionManager;

588

589

public void processPaymentWithCustomTransaction(Payment payment) {

590

// Create custom transaction definition

591

DefaultTransactionDefinition def = new DefaultTransactionDefinition();

592

def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

593

def.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);

594

def.setTimeout(60); // 60 second timeout

595

def.setReadOnly(false);

596

def.setName("PaymentProcessing");

597

598

TransactionStatus status = transactionManager.getTransaction(def);

599

600

try {

601

// Validate payment

602

validatePayment(payment);

603

604

// Process payment

605

processPaymentInternal(payment);

606

607

// Check transaction status

608

if (!status.isRollbackOnly()) {

609

// Create savepoint for partial rollback capability

610

Object savepoint = status.createSavepoint();

611

612

try {

613

// Additional processing that might fail

614

sendPaymentNotification(payment);

615

} catch (Exception ex) {

616

// Rollback to savepoint

617

status.rollbackToSavepoint(savepoint);

618

log.warn("Notification failed, but payment processed", ex);

619

}

620

}

621

622

transactionManager.commit(status);

623

624

} catch (Exception ex) {

625

if (!status.isCompleted()) {

626

transactionManager.rollback(status);

627

}

628

throw new PaymentProcessingException("Payment processing failed", ex);

629

}

630

}

631

}

632

```

633

634

## Types

635

636

```java { .api }

637

import org.springframework.transaction.PlatformTransactionManager;

638

import org.springframework.transaction.TransactionDefinition;

639

import org.springframework.transaction.TransactionStatus;

640

import org.springframework.transaction.TransactionException;

641

import org.springframework.transaction.annotation.Transactional;

642

import org.springframework.transaction.annotation.EnableTransactionManagement;

643

import org.springframework.transaction.annotation.Propagation;

644

import org.springframework.transaction.annotation.Isolation;

645

import org.springframework.transaction.support.TransactionSynchronization;

646

import org.springframework.transaction.support.TransactionSynchronizationManager;

647

import org.springframework.transaction.support.DefaultTransactionDefinition;

648

import org.springframework.transaction.support.DefaultTransactionStatus;

649

import org.springframework.transaction.interceptor.TransactionInterceptor;

650

import org.springframework.transaction.interceptor.TransactionAttributeSource;

651

import org.springframework.orm.jpa.JpaTransactionManager;

652

import org.springframework.orm.hibernate5.HibernateTransactionManager;

653

import jakarta.persistence.EntityManagerFactory;

654

import org.hibernate.SessionFactory;

655

import javax.sql.DataSource;

656

import java.util.Properties;

657

import java.util.function.Consumer;

658

import java.util.Map;

659

import java.util.List;

660

```