ट्रांजैक्शन
Weaver ORM provides TransactionManager, a dedicated service for managing database transactions. It supports simple atomic blocks, manual begin/commit/rollback, nested transactions via savepoints, and optimistic locking.
TransactionManager
Inject Weaver\ORM\Transaction\TransactionManager wherever you need transaction control:
<?php
use Weaver\ORM\Transaction\TransactionManager;
class OrderService
{
public function __construct(
private readonly TransactionManager $txManager,
private readonly EntityWorkspace $workspace,
) {}
}
run(callable $callback) — atomic block
The simplest and recommended way to wrap work in a transaction. Pass a callable; run() begins a transaction, executes the callable, and commits. If the callable throws, the transaction is rolled back automatically and the exception is re-thrown.
<?php
$this->txManager->run(function (): void {
$order = new Order(customerId: $customerId);
$this->workspace->add($order);
foreach ($lineItems as $item) {
$this->workspace->add($item);
}
$this->workspace->push(); // INSERTs run inside the transaction
});
// auto-committed here, or rolled back if an exception was thrown
The return value of the callable is forwarded as the return value of run():
<?php
$orderId = $this->txManager->run(function () use ($data): int {
$order = Order::fromArray($data);
$this->workspace->add($order);
$this->workspace->push();
return $order->getId();
});
Manual begin / commit / rollback
For cases where you need fine-grained control over the transaction lifecycle:
begin()
Opens a new transaction. Throws TransactionException if a transaction is already active.
<?php
$this->txManager->begin();
commit()
Commits the active transaction.
<?php
$this->txManager->commit();
rollback()
Rolls back the active transaction.
<?php
$this->txManager->rollback();
Full example
<?php
$this->txManager->begin();
try {
$account = $this->accountRepo->findOrFail($id);
$account->debit($amount);
$this->workspace->push();
$this->ledgerService->record($account, $amount);
$this->txManager->commit();
} catch (\Throwable $e) {
$this->txManager->rollback();
throw $e;
}
Nested transactions
Weaver ORM supports nested transaction calls transparently through savepoints.
When begin() is called while a transaction is already active, a savepoint is created instead of opening a second transaction. commit() releases the savepoint; rollback() rolls back only to the savepoint, leaving the outer transaction intact.
<?php
$this->txManager->run(function (): void {
// Outer transaction
$this->workspace->add($invoice);
$this->workspace->push();
// Inner block — creates a savepoint internally
$this->txManager->run(function (): void {
$this->workspace->add($auditEntry);
$this->workspace->push();
// savepoint released (partial commit within outer tx)
});
// Outer transaction still open here
$this->workspace->add($notification);
$this->workspace->push();
});
// Outer transaction committed
If the inner block throws and its rollback is caught by the caller, the outer transaction can continue:
<?php
$this->txManager->run(function (): void {
$this->workspace->add($order);
$this->workspace->push();
try {
// attempt to send notification — non-critical
$this->txManager->run(function (): void {
$this->notificationService->send($order);
});
} catch (NotificationException $e) {
// notification failed but the savepoint is rolled back,
// the outer transaction (and the order INSERT) remains intact
$this->logger->warning('Notification failed', ['exception' => $e]);
}
});