/** * {@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); }