Doctrine と Symfony で安全な「テストと設定」操作を行う方法を理解したいです。
私は会議スケジューリングシステムを構築しています。私はと呼ばれるエンティティを持っています
MeetingTime、教師と生徒
特に、MeetingTime には、NULL 可能な多対 1 の Student との関係と、多対 1 の Teacher との関係があります。
meetingTime の Student プロパティは、適切なプロパティが現在 null の場合にのみ保存できるようにしたいと考えています。つまり、ある生徒が別の生徒を上書きできないようにする必要があります。時間を予約する最初の学生が勝ちます。トランザクションがこれを行うようです。
私はこれをやっています:
$saved = true;
try
{
$em->transactional(function($em) use($mtId, $student) {
$mt = $em->getRepository('MyBundle:MeetingTime')->find($mtId);
if (is_null($mt->getStudent()))
{
$mt->setStudent($student);
$em->persist($mt);
}
else
{
throw new Exception();
}
});
}
catch(Exception $e)
{
$saved = false;
}
if (!$saved)
{
// flash "Sorry,, somebody else just grabbed that time".
}
私のUIは、その時間がかかる場合、ページに「今回は予約」ボタンを表示しないことで、このほとんどに対処しますが、もちろん、2人が同時にそれを行う場合、データベースが最終決定権を持ちます.
それはうまくいくようですが、これは正しい方法ですか?トランザクション的に安全ですか?
最初に、MeetingTime に対して 1 対 1 で、Student に対して多対 1 で、MeetingTime に対して一意の制約を持つ追加の「予約」エンティティを使用して実装しました。それは問題なく機能しますが、MeetingTime のプロパティとして Student を使用する方が優れています。これは、学生が教師との会議を 1 回しか予約できないため、MeetingTime に Student と Teacher を組み合わせた一意の制約を持たせたいからです。
例外の種類を知るために、おそらく独自の Exception クラスを作成する必要があることはわかっています。正しい生徒がすでに設定されている場合も、それを幸せにする必要があります。
重要な場合、データベースは PostgreSQL です。これはトリガーを使用して非常に効率的に実行できると確信していますが...それは私が行ったことのない世界全体であり、このデータベースにとらわれないようにしておくとよいでしょう。
ありがとう