Subsequent to this release, we’ve added a new Narayana Spring Boot quickstart to our repository. It is a very much simplified stock market application where users can buy and sell shares. Every transaction executes a couple of database updates and sends a few notifications to a message queue. I’m not going to go through the code in this quickstart in depth, because most of it is pretty straightforward. However, there are a few bits which needs an explanation.
Making sure we are using Narayana
To begin with let’s go through the setup. Most of the necessary dependencies can be added by Spring Initializr:
Notice how “Narayana (JTA)” has been added to the “Selected Dependencies”.
Making sure we are using the right version of Narayana
Now, we need to make sure we’re running the latest version of Narayana. There are a number of options to do that as explained in a post on a Spring blog. But in this case, overriding version property is the easiest option:
<narayana.version>5.5.1.Final</narayana.version>
You can see this in the applications pom over here.<jboss-transaction-spi.version>7.5.0.Final</jboss-transaction-spi.version>
Observing the transaction demarcation
In this application, both buying and selling operations are transactional. Buy method looks like this:
And sell method looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@PutMapping("/portfolio/{username}/{symbol}") | |
@Transactional | |
public void buy(@PathVariable String username, @PathVariable String symbol, @RequestParam("amount") int amount) { | |
User user = getUser(username); | |
Share share = getShare(symbol); | |
PortfolioEntry portfolioEntry = getOrCreatePortfolioEntry(user, share); // Get user's portfolio entry or create a new one | |
updateBudget(user, -1 * amount * share.getPrice()); // Decrease user's budget | |
updateSharesAmount(share, -1 * amount); // Decrease shares amount available for sale | |
updatePortfolioEntry(portfolioEntry, amount); // Increase shares amount owned by the user | |
sendUpdate(String.format("'%s' just bought %d shares of '%s' for the amount of %d", username, amount, symbol, | |
amount * share.getPrice())); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@DeleteMapping("/portfolio/{username}/{symbol}") | |
@Transactional | |
public void sell(@PathVariable String username, @PathVariable String symbol, @RequestParam("amount") int amount) { | |
User user = getUser(username); | |
Share share = getShare(symbol); | |
PortfolioEntry portfolioEntry = getPortfolioEntry(user, share); | |
updateBudget(user, amount * share.getPrice()); // Increase user's budget | |
updateSharesAmount(share, amount); // Increase shares amount available for sale | |
updatePortfolioEntry(portfolioEntry, -1 * amount); // Decrease shares amount owned by the user | |
sendUpdate(String.format("'%s' just sold %d shares of '%s' for the amount of %d", username, amount, symbol, | |
amount * share.getPrice())); | |
} |
Note on Artemis
Artemis broker is not available on Spring Initializr and to make our application self contained we would like to use an embedded broker. To do this we add the following dependency into the applications pom:
Everything else is quite self explanatory. Go ahead and try it out over here.<dependency><groupId>org.apache.activemq</groupId><artifactId>artemis-jms-server</artifactId></dependency>
If you have comments or feedback please do contact us over on our forum.