Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing ACID Transactions #52

Merged
merged 3 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/packages/doctrine.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[
'dbal' => [
'url' => '%env(resolve:DATABASE_URL)%',
'use_savepoints' => true, // Needed for nested transactions
yceruto marked this conversation as resolved.
Show resolved Hide resolved
],
'orm' => [
'report_fields_where_declared' => true,
Expand Down
6 changes: 5 additions & 1 deletion config/packages/messenger.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
'messenger' => [
'default_bus' => 'command.bus',
'buses' => [
'command.bus' => [],
'command.bus' => 'test' === $containerConfigurator->env() ? [] : [
'middleware' => [
'messenger.middleware.doctrine_transaction',
],
],
'query.bus' => [],
],
'transports' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public function __invoke(AnonymizeBooksCommand $command): void
$book->update(
author: new Author($command->anonymizedName),
);

$this->bookRepository->save($book);
chalasr marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#[AsCommandHandler]
final readonly class CreateBookCommandHandler
{
public function __construct(private readonly BookRepositoryInterface $bookRepository)
public function __construct(private BookRepositoryInterface $bookRepository)
{
}

Expand All @@ -25,7 +25,7 @@ public function __invoke(CreateBookCommand $command): Book
$command->price,
);

$this->bookRepository->save($book);
$this->bookRepository->add($book);

return $book;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,5 @@ public function __invoke(DiscountBookCommand $command): void
}

$book->applyDiscount($command->discount);

$this->bookRepository->save($book);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ public function __invoke(UpdateBookCommand $command): Book
price: $command->price,
);

$this->bookRepository->save($book);

return $book;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
interface BookRepositoryInterface extends RepositoryInterface
{
public function save(Book $book): void;
public function add(Book $book): void;

public function remove(Book $book): void;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ public function __construct(EntityManagerInterface $em)
parent::__construct($em, self::ENTITY_CLASS, self::ALIAS);
}

public function save(Book $book): void
public function add(Book $book): void
{
$this->em->persist($book);
$this->em->flush();
}

public function remove(Book $book): void
{
$this->em->remove($book);
$this->em->flush();
}

public function ofId(BookId $id): ?Book
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
final class InMemoryBookRepository extends InMemoryRepository implements BookRepositoryInterface
{
public function save(Book $book): void
public function add(Book $book): void
{
$this->entities[(string) $book->id()] = $book;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/BookStore/Acceptance/AnonymizeBooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function testAnonymizeAuthorOfBooks(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

for ($i = 0; $i < 10; ++$i) {
$bookRepository->save(DummyBookFactory::createBook(author: sprintf('author_%d', $i)));
$bookRepository->add(DummyBookFactory::createBook(author: sprintf('author_%d', $i)));
}

$response = $client->request('POST', '/api/books/anonymize', [
Expand Down
16 changes: 8 additions & 8 deletions tests/BookStore/Acceptance/BookCrudTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function testReturnPaginatedBooks(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

for ($i = 0; $i < 100; ++$i) {
$bookRepository->save(DummyBookFactory::createBook());
$bookRepository->add(DummyBookFactory::createBook());
}

$client->request('GET', '/api/books');
Expand All @@ -51,9 +51,9 @@ public function testFilterBooksByAuthor(): void
/** @var BookRepositoryInterface $bookRepository */
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

$bookRepository->save(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->save(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->save(DummyBookFactory::createBook(author: 'authorTwo'));
$bookRepository->add(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->add(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->add(DummyBookFactory::createBook(author: 'authorTwo'));

$client->request('GET', '/api/books?author=authorOne');

Expand Down Expand Up @@ -83,7 +83,7 @@ public function testReturnBook(): void
content: 'content',
price: 1000,
);
$bookRepository->save($book);
$bookRepository->add($book);

$client->request('GET', sprintf('/api/books/%s', (string) $book->id()));

Expand Down Expand Up @@ -186,7 +186,7 @@ public function testUpdateBook(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

$book = DummyBookFactory::createBook();
$bookRepository->save($book);
$bookRepository->add($book);

$client->request('PUT', sprintf('/api/books/%s', $book->id()), [
'json' => [
Expand Down Expand Up @@ -227,7 +227,7 @@ public function testPartiallyUpdateBook(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

$book = DummyBookFactory::createBook(name: 'name', description: 'description');
$bookRepository->save($book);
$bookRepository->add($book);

$client->request('PATCH', sprintf('/api/books/%s', $book->id()), [
'headers' => [
Expand Down Expand Up @@ -260,7 +260,7 @@ public function testDeleteBook(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

$book = DummyBookFactory::createBook();
$bookRepository->save($book);
$bookRepository->add($book);

$response = $client->request('DELETE', sprintf('/api/books/%s', $book->id()));

Expand Down
4 changes: 2 additions & 2 deletions tests/BookStore/Acceptance/CheapestBooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function testReturnOnlyTheTenCheapestBooks(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

for ($i = 0; $i < 20; ++$i) {
$bookRepository->save(DummyBookFactory::createBook(price: $i));
$bookRepository->add(DummyBookFactory::createBook(price: $i));
}

$response = $client->request('GET', '/api/books/cheapest');
Expand All @@ -46,7 +46,7 @@ public function testReturnBooksSortedByPrice(): void

$prices = [2000, 1000, 3000];
foreach ($prices as $price) {
$bookRepository->save(DummyBookFactory::createBook(price: $price));
$bookRepository->add(DummyBookFactory::createBook(price: $price));
}

$response = $client->request('GET', '/api/books/cheapest');
Expand Down
4 changes: 2 additions & 2 deletions tests/BookStore/Acceptance/DiscountBookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testApplyADiscountOnBook(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

$book = DummyBookFactory::createBook(price: 1000);
$bookRepository->save($book);
$bookRepository->add($book);

$client->request('POST', sprintf('/api/books/%s/discount', $book->id()), [
'json' => [
Expand All @@ -43,7 +43,7 @@ public function testValidateDiscountAmount(): void
$bookRepository = static::getContainer()->get(BookRepositoryInterface::class);

$book = DummyBookFactory::createBook(price: 1000);
$bookRepository->save($book);
$bookRepository->add($book);

$client->request('POST', sprintf('/api/books/%s/discount', $book->id()), [
'json' => [
Expand Down
2 changes: 1 addition & 1 deletion tests/BookStore/Functional/AnonymizeBooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function testAnonymizeAuthorOfBooks(): void
$commandBus = static::getContainer()->get(CommandBusInterface::class);

for ($i = 0; $i < 10; ++$i) {
$bookRepository->save(DummyBookFactory::createBook(author: sprintf('author_%d', $i)));
$bookRepository->add(DummyBookFactory::createBook(author: sprintf('author_%d', $i)));
}

$commandBus->dispatch(new AnonymizeBooksCommand('anon.'));
Expand Down
2 changes: 1 addition & 1 deletion tests/BookStore/Functional/DeleteBookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function testDeleteBook(): void
$commandBus = static::getContainer()->get(CommandBusInterface::class);

$book = DummyBookFactory::createBook();
$bookRepository->save($book);
$bookRepository->add($book);

static::assertCount(1, $bookRepository);

Expand Down
2 changes: 1 addition & 1 deletion tests/BookStore/Functional/DiscountBookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function testApplyADiscountOnBook(int $initialAmount, int $discount, int
$commandBus = static::getContainer()->get(CommandBusInterface::class);

$book = DummyBookFactory::createBook(price: $initialAmount);
$bookRepository->save($book);
$bookRepository->add($book);

$commandBus->dispatch(new DiscountBookCommand($book->id(), new Discount($discount)));

Expand Down
2 changes: 1 addition & 1 deletion tests/BookStore/Functional/FindBookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function testFindBook(): void
$queryBus = static::getContainer()->get(QueryBusInterface::class);

$book = DummyBookFactory::createBook();
$bookRepository->save($book);
$bookRepository->add($book);

static::assertSame($book, $queryBus->ask(new FindBookQuery($book->id())));
}
Expand Down
10 changes: 5 additions & 5 deletions tests/BookStore/Functional/FindBooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function testFindBooks(): void
];

foreach ($initialBooks as $book) {
$bookRepository->save($book);
$bookRepository->add($book);
}

$books = $queryBus->ask(new FindBooksQuery());
Expand All @@ -49,9 +49,9 @@ public function testFilterBooksByAuthor(): void
/** @var QueryBusInterface $queryBus */
$queryBus = static::getContainer()->get(QueryBusInterface::class);

$bookRepository->save(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->save(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->save(DummyBookFactory::createBook(author: 'authorTwo'));
$bookRepository->add(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->add(DummyBookFactory::createBook(author: 'authorOne'));
$bookRepository->add(DummyBookFactory::createBook(author: 'authorTwo'));

static::assertCount(3, $bookRepository);

Expand Down Expand Up @@ -80,7 +80,7 @@ public function testReturnPaginatedBooks(): void
];

foreach ($initialBooks as $book) {
$bookRepository->save($book);
$bookRepository->add($book);
}

$books = $queryBus->ask(new FindBooksQuery(page: 2, itemsPerPage: 2));
Expand Down
4 changes: 2 additions & 2 deletions tests/BookStore/Functional/FindCheapestBooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function testReturnOnlyTheCheapestBooks(): void
$queryBus = static::getContainer()->get(QueryBusInterface::class);

for ($i = 0; $i < 5; ++$i) {
$bookRepository->save(DummyBookFactory::createBook());
$bookRepository->add(DummyBookFactory::createBook());
}

$cheapestBooks = $queryBus->ask(new FindCheapestBooksQuery(3));
Expand All @@ -40,7 +40,7 @@ public function testReturnBooksSortedByPrice(): void

$prices = [2000, 1000, 3000];
foreach ($prices as $price) {
$bookRepository->save(DummyBookFactory::createBook(price: $price));
$bookRepository->add(DummyBookFactory::createBook(price: $price));
}

$cheapestBooks = $queryBus->ask(new FindCheapestBooksQuery(3));
Expand Down
2 changes: 1 addition & 1 deletion tests/BookStore/Functional/UpdateBookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function testUpdateBook(): void
price: 1000,
);

$bookRepository->save($initialBook);
$bookRepository->add($initialBook);

$commandBus->dispatch(new UpdateBookCommand(
$initialBook->id(),
Expand Down
Loading
Loading