bentools/doctrine-safe-events 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

bentools/doctrine-safe-events

最新稳定版本:1.0.1

Composer 安装命令:

composer require bentools/doctrine-safe-events

包简介

Fires postPersist / postUpdate / postRemove events AFTER the transaction has completed.

README 文档

README

CI Workflow Coverage

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)

Background

The idea of this repository indeed came up with the following issue:

  • An entity is persisted, then $em->flush() is called
  • A postPersist event 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 EntityNotFound exception (the COMMIT did not happen yet)
  • The flush operation on the main thread completes, and the postFlush event 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 implement safePostPersist as a replacement of postPersist)
  • Bentools\DoctrineSafeEvents\SafeEvents::POST_UPDATE (and implement safePostUpdate as a replacement of postUpdate)
  • Bentools\DoctrineSafeEvents\SafeEvents::POST_REMOVE (and implement safePostRemove as a replacement of postRemove)

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.

统计信息

  • 总下载量: 9.98k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 2
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-01-04