0

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 です。これはトリガーを使用して非常に効率的に実行できると確信していますが...それは私が行ったことのない世界全体であり、このデータベースにとらわれないようにしておくとよいでしょう。

ありがとう

4

2 に答える 2

0

ここではトランザクションは役に立ちません。フラッシュが成功することを保証します。何もロックしません。

ここまで読んでください: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html

テーブルにバージョン番号を追加し、@Version タグでフラグを立てるだけでよい楽観的ロックを使用することをお勧めします。そしてビオラ!フラッシュ時に発生する可能性のある例外をキャッチする準備をする必要がありますが、並行性の問題はもうありません。

$mt->setStudent の内部にヌル チェックを入れて、常に発生するようにすることを検討してください。

于 2013-08-16T20:28:46.037 に答える
0

ID と null の学生の両方を持つ MeetingTime エンティティをリポジトリで検索します。見つかった場合は、生徒を設定できます。それ以外の場合は、運が悪いと生徒に伝えます。

まだ作成していない場合は、このために独自のリポジトリ クラスを作成する必要があります。

多くの学生が同時に予約していない限り、同時実行の問題になるとは思えません。

Doctrine には悲観的ロック オプションもありますが、いくつかの注意点があります: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html#pessimistic-ロック

于 2013-08-17T02:12:36.507 に答える