/**
  * {@inheritdoc}
  */
 public function invoke(MethodInvocation $invocation)
 {
     $annotation = $this->extractAnnotation($invocation->getMethod(), Transactional::class);
     $scope = new TransactionScope(new DbalTransaction($this->conn, $annotation), $annotation);
     return $scope->runInto(function () use($invocation) {
         return $invocation->proceed();
     });
 }
 /**
  * @test
  */
 public function test_rollbacking_nested_transaction()
 {
     $dir = __DIR__;
     $config = "driver=pdo_sqlite&path={$dir}/../var/db/todo.sqlite3";
     $injector = new Injector(new TestModule($config));
     $annotation = new Transactional();
     $annotation->txType = TransactionScope::REQUIRES_NEW;
     $trans = new DbalTransaction($injector->getInstance(Connection::class), $annotation);
     $scope = new TransactionScope($trans, $annotation);
     $model = $injector->getInstance(TodoModel::class);
     $scope->runInto(function () use($model) {
         $this->assertTrue($model->select(999) === false);
         $this->assertTrue($model->select(888) === false);
         try {
             $model->insertRecordAllowingNestedTransaction(999, 'test memo');
             $model->insertFailAllowingNestedTransaction(888, 'failed', function ($m) {
                 $row = $m->select(888);
                 $this->assertFalse($row === false);
                 $this->assertEquals(888, $row['id']);
                 $this->assertEquals('failed', $row['todo']);
             });
         } catch (\LogicException $ex) {
         }
         $row = $model->select(999);
         $this->assertFalse($row === false);
         $this->assertEquals(999, $row['id']);
         $this->assertEquals('test memo', $row['todo']);
         // For latter transaction, Rollback is not executed.
         $this->assertTrue($model->select(888) === false);
     });
     $row = $model->select(999);
     $this->assertFalse($row === false);
     $this->assertEquals(999, $row['id']);
     $this->assertEquals('test memo', $row['todo']);
     // For latter transaction, Rollback is not executed.
     $this->assertTrue($model->select(888) === false);
 }
 /**
  * @test
  */
 public function test_using_nested_transaction()
 {
     $tran = new TransactionStub();
     $tran->begin();
     $annotation = new Transactional();
     $annotation->txType = TransactionScope::REQUIRES_NEW;
     $scope = new TransactionScope($tran, $annotation);
     $this->assertEquals(1, $tran->depth());
     $scope->runInto(function () use($tran) {
         $this->assertEquals(2, $tran->depth());
     });
     $this->assertEquals(1, $tran->depth());
 }
 /**
  * @test
  */
 public function test_commiting_after_rollback_nested_transaction_insertion_row()
 {
     $annotation = new Transactional();
     $annotation->txType = TransactionScope::REQUIRES_NEW;
     $conn = $this->getConnection();
     $trans = new DbalTransaction($conn, $annotation);
     $scope = new TransactionScope($trans, $annotation);
     $dao = new DaoStub();
     $this->assertTrue($dao->select($conn, 999) === false);
     $this->assertTrue($dao->select($conn, 888) === false);
     try {
         $scope->runInto(function () use($dao, $conn, $scope) {
             $dao->insert($conn, 999, 'transaction test');
             $row = $dao->select($conn, 999);
             $this->assertFalse($row === false);
             $this->assertEquals(999, $row['id']);
             $this->assertEquals('transaction test', $row['todo']);
             $this->assertTrue($dao->select($conn, 888) === false);
             $scope->runInto(function () use($dao, $conn) {
                 $dao->insert($conn, 888, 'nested transaction test');
                 $row = $dao->select($conn, 888);
                 $this->assertFalse($row === false);
                 $this->assertEquals(888, $row['id']);
                 $this->assertEquals('nested transaction test', $row['todo']);
             });
             $row = $dao->select($conn, 888);
             $this->assertFalse($row === false);
             $this->assertEquals(888, $row['id']);
             $this->assertEquals('nested transaction test', $row['todo']);
             $row = $dao->select($conn, 999);
             $this->assertFalse($row === false);
             $this->assertEquals(999, $row['id']);
             $this->assertEquals('transaction test', $row['todo']);
             throw new \LogicException('ERROR');
         });
     } catch (\LogicException $ex) {
     }
     $this->assertTrue($dao->select($conn, 999) === false);
     $this->assertTrue($dao->select($conn, 888) === false);
 }