bentools/doctrine-safe-events
Composer 安装命令:
composer require bentools/doctrine-safe-events
包简介
Fires postPersist / postUpdate / postRemove events AFTER the transaction has completed.
README 文档
README
Doctrine safe post* events
Doctrine's postPersist, postUpdate and postRemove events are fired when the corresponding SQL queries (INSERT / UPDATE / DELETE) have been performed against the database server.
What happens under the hood is that Doctrine creates a wrapping transaction, runs SQL queries, then commits the transaction.
However, these events are fired immediately, e.g. not once the transaction is complete, which means:
- If the wrapping transaction fails, events have already been fired anyway (meaning you trusted generated primary key values, although they're going to be rolled back)
- If the wrapping transaction takes some time (typically during row locks), you get the inserted / updated / deleted information before it's actually done (meaning if you run some async process once those events are triggered, you end up in processing not data which is not up-to-date)
Doctrine ORM documentation states:
Warning
At the time postPersist is called, there may still be collection and/or "extra" updates pending. The database may not yet be completely in sync with the entity states in memory, not even for the new entities.
Similarly, also at the time postUpdate and postRemove are called, in-memory collections may still be in a "dirty" state or still contain removed entities.
Background
The idea of this repository indeed came up with the following issue:
- An entity is persisted, then
$em->flush()is called - A
postPersistevent listener gets the entity's id, then asks a worker to do some async processing through Symfony Messenger - The worker queries database against the entity's id, and gets an
EntityNotFoundexception (theCOMMITdid not happen yet) - The flush operation on the main thread completes, and the
postFlushevent is fired (but it does not contain the inserted / updated / deleted entities)
Our solution
If you run into the same kind of issues, you can replace your listeners' listened events in favor of:
Bentools\DoctrineSafeEvents\SafeEvents::POST_PERSIST(and implementsafePostPersistas a replacement ofpostPersist)Bentools\DoctrineSafeEvents\SafeEvents::POST_UPDATE(and implementsafePostUpdateas a replacement ofpostUpdate)Bentools\DoctrineSafeEvents\SafeEvents::POST_REMOVE(and implementsafePostRemoveas a replacement ofpostRemove)
Basically, this library will collect entities which are scheduled for insertion / update / deletion, except it will delay event firing until the postFlush occurs.
Installation
composer require bentools/doctrine-safe-events
Usage in Symfony
Although this library has no dependency on Symfony, you can easily use it in your Symfony project:
Bentools\DoctrineSafeEvents\SafeEventsDispatcher: tags: - { name: 'doctrine.event_subscriber' } - { name: 'kernel.reset', method: 'reset' }
Example usage
declare(strict_types=1); namespace App; use Bentools\DoctrineSafeEvents\SafeEvents; use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener; use Doctrine\Persistence\Event\LifecycleEventArgs; #[AsDoctrineListener(SafeEvents::POST_PERSIST)] final class SomeListener { public function safePostPersist(LifecycleEventArgs $eventArgs): void { // ... } }
Tests
composer test
License
MIT.
bentools/doctrine-safe-events 适用场景与选型建议
bentools/doctrine-safe-events 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 12.97k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2023 年 01 月 04 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 bentools/doctrine-safe-events 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 bentools/doctrine-safe-events 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 12.97k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-01-04