私たちの Symfony2 プロジェクトでは、リソース間の変更がトランザクションであることを保証したいと考えています。たとえば、次のようなものです。
namespace ...;
use .../TransactionManager;
class MyService {
protected $tm;
public function __construct(TransactionManager $tm)
{
$this->tm = $tm;
}
/**
* @ManagedTransaction
*/
public function doSomethingAcrossResources()
{
...
// where tm is the transaction manager
// tm is exposing a Doctrine EntityManager adapter here
$this->tm->em->persist($entity);
...
// tm is exposing a redis adapter here
$this->tm->redis->set('foo', 'bar');
if ($somethingWentWrong) {
throw new Exception('Something went terribly wrong');
}
}
}
したがって、ここで注意すべき点がいくつかあります。
- すべてのリソースには、その API を公開するアダプターが必要です (Doctrine アダプター、Redis アダプター、Memcache アダプター、File アダプターなど)。
- 何か問題が発生した場合 (例外がスローされた場合)、管理対象リソースには何も書き込まれません (つまり、すべてがロールバックされます)。
- 何も問題がなければ、すべてのリソースが期待どおりに更新されます
- doSomethingAcrossResources 関数は、たとえば Files や Memcache などの非トランザクション リソースに加えた変更を元に戻すことを心配する必要はありません。これが重要です。そうしないと、このコードは、適切なタイミングで redis に書き込むだけの複雑な混乱になる可能性があるためです。
- @ManagedTransacton アノテーションが残りを処理します (コミット/ロールバック/必要なトランザクションの開始 (アダプターに基づく) など)。
- 最も単純な実装では、tm は単純にキューを管理し、すべてのアイテムを順番にキューから取り出すことができます。例外がスローされた場合、何もキューから取り出されません。したがって、アダプタは、キュー内の各項目をコミットする方法に関するトランザクション マネージャの知識です。
- デキュー中に例外が発生した場合、トランザクション マネージャは、すでにデキューされたアイテム (おそらくロールバック スタックに配置されている) をロールバックする方法についてアダプタを調べます。これは、変更を簡単にロールバックするために内部でトランザクションを管理する必要がある EntityManager のようなリソースでは扱いにくい場合があります。ただし、redis アダプターは、更新中に以前の値をキャッシュするか、ロールバック中に単に DELETE を発行する ADD 中にキャッシュする場合があります。
このようなトランザクション マネージャーは既に存在しますか? これらの目標を達成するためのより良い方法はありますか? 私が見落としているかもしれない警告はありますか?
ありがとう!