One transaction or two transactions by Axon?

I have two aggregates: Book and Reader. One reader can borrow up to 3 books. When a read borrows a book, I need to add this book to his borrowed book list, and the same time I need to update the book to save the reader as the current borrower.

The client sends a BorrowCommand

bookCommandGateway.sendAndWait(new BorrowCommand(readerId, req.getBookId()), 3000, TimeUnit.MILLISECONDS);

Both BookEventListener and ReaderEventListener event handlers will handle BorrowEvent.

My question:

  1. Is this a good design? Does this count as one command modifies 2 aggregates in a single transaction?

  2. How many transactions Axon will execute for this BorrowCommand? One or two? One for aggregate Book and one for aggregate Reader?

(Sorry for the long code followed.)

This design looks ok. In this case, a command only affects a single aggregate. That one command produces an event that is handled by two components to update two query models. It’s better to be really clear about the role of your classes. Use the suffix Command and Event for the respective types of classes, so that you don’t mix them up.

Howmany transaction are involved depends on the infrastructure components. 1 command is 1 transaction. If you handle events asynchronously, it’s an extra transaction for each async handling. Conceptually, each message is its own transaction. If you don’t rely on multiple messages (command and resulting event handling) being handled in the same transaction, you achieve the best flexibility.