Transactions
Starting with MongoDB version 4.0, multi-document transactions are now supported on replica sets.
Morphia 2.0 introduces a simple mechanism to access this functionality.
Morphia 2.0 adds the methods withTransaction(MorphiaTransaction<T> transaction)
and
withTransaction(ClientSessionOptions options, MorphiaTransaction<T> transaction)
allowing for the execution of logic scoped to a transaction.
The API is designed to work with Java 8’s lambda syntax for the most convenience. In this example, let’s assume we’re building a shopping site.
User account = datastore.withTransaction((session) -> {
User user = new User("jimbo", "jimhalpert@dundermifflin.com");
user.setHomeAddress(new Address("123 Paper Lane", "Scranton", "PA", "18510"));
return session.save(user);
});
In this simple example, we’re starting with our standard Datastore
and calling withTransaction()
.
The lambda we’re passing in executes all with the scope of a single transaction.
You’ll note the single parameter passed in is a MorphiaSession
.
This is actually a Datastore
but it has been bound to a session.
Any changes to be made within the transaction should be made using this
session
reference.
Once the lambda returns, the transaction is automatically committed and the session closed.
If you need access to server session or the transaction, there are methods on MorphiaSession
to return either of those.
Of course, it’s not always possible to wrap things up neatly inside a lambda so let’s take a look at more hands on approach:
MorphiaSession session = datastore.startSession();
session.startTransaction();
User user = new User("jimbo", "jimhalpert@dundermifflin.com");
user.setHomeAddress(new Address("123 Paper Lane", "Scranton", "PA", "18510"));
session.save(user);
session.commitTransaction();
session.close();
This is essentially the same logic as above but now we’re manually managing the transactional boundaries. MorphiaSession
is also
AutoCloseable
so you could wrap the entire block in a try-with-resources
block and let that manage the session boundary for you:
try(MorphiaSession session = datastore.startSession()) {
session.startTransaction();
User user = new User("jimbo", "jimhalpert@dundermifflin.com");
user.setHomeAddress(new Address("123 Paper Lane", "Scranton", "PA", "18510"));
session.save(user);
session.commitTransaction();
}