2017-08-09 14 views
0

特定のコントローラでは、データベース内でいくつかの挿入/更新を行う必要があります。私は4つのエンティティの4つのリポジトリを使用していますが、これを作業単位で行う必要があります。Symfony。 2つ以上のリポジトリとのトランザクションの使用

これらの挿入/更新はコントローラで直接行うことができ、$em->getConnection()->beginTransaction(),$em->getConnection()->rollBack()および$em->getConnection()->commit()を使用して、すべてまたはすべてが完了していることを確認できます。しかしこれはsymfonyのベストプラクティスに反するので、私はリポジトリを使いたいと思います。

私はDoctrine 1のためにthis tutorialを見たことがありますが、それはもっと簡単なものになる非常に複雑な解決策のようです。

ありがとうございます。

編集、私はSymfony 3.3.5を使用しています。

edit2、私は何をしたいかの例を追加します。全体のプロセスは、会社内のすべての部門メイトに作業者が書いたメッセージを追加することです。メッセージには添付ファイルがある場合と添付されていない場合があります。これらのファイルは部署と会社のファイルとして表示されるため、部署が削除されても、ファイルは引き続き会社の所属として表示されます。

私はコードにエラー処理を含めていないので、簡単に処理できます。

// New Files 
$file1 = new File(); // AppBundle\Entity\File 
$file1->setName("name1"); 
$file2 = new File(); 
$file2->setName("name2"); 

$em->getRepository('AppBundle:File')->insert($file1); 
$em->getRepository('AppBundle:File')->insert($file2); 

// New Post 
$post = new Post(); // AppBundle\Entity\Post 
$post->setContent($some_text) 
    ->setAuthor($some_user) // AppBundle\Entity\User 
    ->addFile($file1) 
    ->addFile($file2); 

$em->getRepository('AppBundle:Post')->insert($post); 

// Getting company and department 
$company = $em->getRepository('AppBundle:Company')->findOneByCode($some_company_code); 
$department = $em->getRepository('AppBundle:Department')->findOneByCode($some_dept_code); 

$company->addFile($file1)->addFile($file2); 
$department->addFile($file1)->addFile($file2); 

$em->getRepository('AppBundle:Company')->update($company); 
$em->getRepository('AppBundle:Department')->update($department); 

// Notifications 
$notif = new Notification(); // AppBundle\Entity\Notification 
$notif->setText("Text") 
    ->setPost($post) 
    ->addAddressee($some_dept_member) 
    ->addAddressee($other_dept_member); 

$notif = $em->getRepository('AppBundle:Notification')->insert($notif); 
+0

まず同じように、あなたはコールバック関数にすべてのコードを含めることを検討してエンティティマネージャに渡す必要があり、同じトランザクションでデータをフェッチ/取得する必要がある場合は、」非常に広い質問をしました。コードなしで助けが難しい次に、リポジトリはデータを変更するのではなく、リポジトリをフェッチするだけなので、リポジトリはそのような作業の場所ではありません。 –

+0

'flush()'が呼び出されたとき、doctrineは自動的にすべてのスケジュールされた操作を単一のトランザクション内でラップしませんか?これは助けになるかもしれません:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html – Joe

+0

@Jakub、私は思うので私はコードを書いていませんでしたsymfonyを使った人は誰でも私が求めていることを知ることができます。また、ほとんどの人が直面していることだと思うので、ここで答えが見つからないことは私には驚きです。ドキュメントには、リポジトリについて「Doctrineは、すべてのクエリロジックを1つの中央の場所に保存できる特別なリポジトリクラスを提供しています」と書いています。だからこそ私はそれをやりたかったのです。ジョー、トランザクションの使用方法はわかっていますが、ドキュメントには私が求めていることが説明されていません(または見つからなかった) – DandyCC

答えて

0

リポジトリでは、データを取得するDQLを使用してエンティティを取得したり、クエリを実行したりする必要があります。

dbに新しい行を作成する必要があるたびに、エンティティを永続化することをエンティティマネージャに通知し、$em->persist($myNewEntity)を呼び出します。これはエンティティマネージャに、エンティティをdBに永続化する必要があることを通知します。

すべてのエンティティを作成して(または永続化して)フェッチしたエンティティを変更した後は、$em->persist()を1回だけ呼び出すことができます。エンティティマネージャは、必要な挿入/更新/削除をすべて、 。

あなたはまた、すべてのこの

$myCallback=function($em) { 
    //Do all here: access repositories, create new entities, edit entities 
    //... 
    //no need to call $em->flush(), it will be called by Doctrine after the execution of the callback 
}; 
$em->transactional($myCallback) ; 
関連する問題