Doctrine2とDoctrine1のUnit Of Work

Doctrine2では、エンティティの値をデータベースへ保存する際にUnit Of Workパターンというデザインパターンの実装を使っています。

(twitterで@vectorxenonさんからツッコミがありましたが)Doctrine1でもUnit Of Workという名前のクラスがあります!(私は今までDoctrine1のこのクラスを意識して読んだことがなかったようで、記憶にほとんど残っていませんでしたがw)

しかし、Doctrine1のUnit Of Workクラスには、ソースコードのコメントで以下のように記述されているとおり、本来のUnit Of Workパターンの仕組みは実装されておらず、モデルのsaveメソッドを呼ぶ度にその場でデータベースへアクセスします。

Note: This class does not have the semantics of a real "Unit of Work" in 0.10/1.0.
Database operations are not queued. All changes to objects are immediately written
to the database. You can think of it as a unit of work in auto-flush mode.


Doctrine2では、最初のリンクで示したようなUnit Of Workパターンが実装されていて、以下のような2段階の手順でDBへデータを保存します。

# EntityManagerのpersist()を呼び出すと、その時点でエンティティインスタンスのハッシュがUnit Of Workに追加される
# EntityManagerのflush()を呼び出した時点で、実際にUnit Of Workに追加されているエンティティの中でDBに反映する必要があるものを選び出し、その分だけ処理が行われます。


このような形になっているので、特に更新系の処理が効率よく行われるようです。


また、Unit Of Workが「DBに変更が必要」と判定する部分の処理もカスタマイズが可能で、デフォルトではDeferred Implicitです。
(→Doctrine2のエンティティの変更トラッキング - しんふぉにゃん