dualmedia/doctrine-retry-bundle
Symfony bundle that wraps Doctrine transactions with automatic retries for deadlocks and transient DB errors. Configure optional nesting tracking, then call Retrier->execute() with a closure receiving the EntityManager to safely run retryable work.
A Symfony Bundle for easy retryable database transactions.
Simply composer require dualmedia/doctrine-retry-bundle
Then add the bundle to your config/bundles.php file like so
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
// other bundles ...
DualMedia\DoctrineRetryBundle\DoctrineRetryBundle::class => ['all' => true],
];
You're free to leave the configuration as-is, otherwise all you can change is the following:
dm_doctrine_retry:
track_nesting: '%kernel.debug%' # if true, Retrier will warn you if you nest transaction calls
use DualMedia\DoctrineRetryBundle\Retrier;
use Doctrine\ORM\EntityManagerInterface;
class Foo {
public function __construct(
private readonly Retrier $retrier
) {}
public function doWork(
int $orderId
): void {
$this->retrier->execute(function (EntityManagerInterface $em) use ($orderId): void {
// do some work which may cause deadlocks and such
$order = $em->getRepository(SomeOrder::class)->find($orderId, \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE);
});
}
}
By default, any \Exception thrown inside the callback will be caught, logged, and re-thrown after rolling back the transaction. If you want an exception to bypass retry logic entirely (e.g. a deliberate early exit or a business-logic exception that should propagate immediately without logging), implement PassthroughExceptionInterface:
use DualMedia\DoctrineRetryBundle\Interface\PassthroughExceptionInterface;
class OrderNotFoundException extends \RuntimeException implements PassthroughExceptionInterface {}
When Retrier encounters an exception implementing PassthroughExceptionInterface, it will:
This is useful for intentional control-flow exceptions that should not be treated as database failures.
How can I help you explore Laravel packages today?