Skip to main content
Winter Boot supports two complementary approaches to transaction management. Declarative transactions use the #[Transactional] method annotation — the framework wraps the method in a transaction automatically, handling commit and rollback with no extra code in your business logic. Programmatic transactions give you fine-grained control via PlatformTransactionManager, which is useful when transaction boundaries cannot be expressed as a single method call or when you need to interact with dynamically-resolved data sources such as in multi-tenant scenarios.

Enabling Transaction Management

Before using either approach, add #[EnableTransactionManagement] to your application entry-point class. Without this annotation, the transaction infrastructure is not bootstrapped.
MyApplication.php
Transaction management is opt-in. If you omit #[EnableTransactionManagement], #[Transactional] annotations are silently ignored and no transaction managers are registered.

Declarative Transactions with #[Transactional]

Annotate any service or component method with #[Transactional] to have the framework begin a transaction before the method runs, commit it on success, or roll it back on any uncaught exception.
PaymentService.php
The -txn suffix follows Winter Boot’s automatic bean-naming convention. For each datasource named <name>, the framework registers a transaction manager bean as <name>-txn. You only need the suffix when targeting a non-primary datasource. For the primary datasource, plain #[Transactional] is sufficient.

#[Transactional] Options

string
default:"default"
Bean name of the PlatformTransactionManager to use. Defaults to the primary datasource’s transaction manager.
int
default:"PROPAGATION_REQUIRED"
Transaction propagation behaviour. See the propagation constants table below.
int
default:"ISOLATION_DEFAULT"
Database isolation level to request from the driver.
int
default:"TIMEOUT_DEFAULT"
Transaction timeout in seconds. -1 means use the driver default.
bool
default:"false"
Mark the transaction as read-only. A rollback is performed at the end instead of a commit.
array
default:"all exceptions"
Array of exception class names that must trigger a rollback.
array
default:"none"
Array of exception class names that must not trigger a rollback.
array
default:"[]"
Arbitrary string labels to associate with the transaction for informational purposes.

Propagation Constants


Programmatic Transaction Management

PlatformTransactionManager gives you direct control over the transaction lifecycle. Inject it with #[Autowired] for the primary datasource, or by bean name for a named datasource, then call getTransaction(), commit(), and rollback() yourself.

PlatformTransactionManager Methods

TransactionStatus
Begin or join a transaction according to the given definition.
void
Commit the transaction represented by $status.
void
Roll back the transaction represented by $status.

Configuring a TransactionDefinition

DefaultTransactionDefinition is the standard implementation of TransactionDefinition. Configure it before calling getTransaction():

Complete Programmatic Example

The following service shows the full try/commit/catch/rollback pattern using an injected PlatformTransactionManager:
UserService.php

PDO Nested Transaction Limitation

PDO does not natively support nested (savepoint-based) transactions. PROPAGATION_NESTED is defined in the Transaction interface but falls back to PROPAGATION_REQUIRED behaviour when used with PDO-backed data sources.
If you require true nested transaction semantics, implement a custom PlatformTransactionManager using a driver that supports savepoints and register it as a named bean.

Choosing an Approach

Declarative (#[Transactional])

Best for service-layer methods with straightforward, single-method transaction boundaries. Zero boilerplate — commit and rollback happen automatically based on whether the method throws.

Programmatic (PlatformTransactionManager)

Best when transaction scope spans multiple methods, when you need conditional commits, or when working with multi-tenant dynamic data sources where the transaction manager is resolved at runtime.