Testing guice-persist nested @Transactional behavior
TweetPosted on Wednesday Dec 23, 2015 at 01:41PM in Technology
There is no mention of nested use of @Transactional
in the Transactions page of official Guice Wiki so I’ve done some testing about how transactions will be treated in nested use.
As it turns out, Guice seems ignore any of nested @Transactional
and any of its rollbackOn
attributes. It’s all up to the parent invoker.
For testing, I created two classes as following UML diagram:
EnclosingService
holds a reference to EnclosedService
and invokes a method of it from every method of EnclosingService
. Each name of methods state that what exception will be thrown from the method. For example, EnclosedService#runtimeException()
throws RuntimeException
while EnclosedService#noException()
won’t throw any of Exception. EnclosedService#ioExceptionWithRollbackOn()
throws IOException
and annotated as @Transactional(rollbackOn = IOException.class)
. And names of methods of EnclosingService
states same but the part of after _
means that what method of EnclosedService
will be invoked.
All of methods in both services save a Entity with em.persist()
then invoke em.flush()
so that every changes will be flushed immediately. i.e. EnclosingService#noException_noException()
saves two entities that one in the method itself and another one in the enclosing invocation of EnclosedService#noException()
.
Then I created a test case which has 16 test methods that covers all of methods defined in EnclosingService
and found that any of @Transactional
annotation or rollbackOn
attribute in EnclosedService
are being ignored. I summarized the result in a table:
I can see all of operations are atomic and any Exception thrown in methods of EnclosedService
doesn’t affect the result if the transaction will be committed or rolled back. When Guice detects that it’s a RuntimeException
or a checked exception that defined as rollbackOn
in the first method which annotated as @Transactional
then rollback happen.
All resources that used in this test can be obtained from my GitHub repository. It used in-memory database of Apache Derby so that everyone can execute the testcase without any annoying preparation. Also EclipseLink 2.5.1, Guice 3.0 and log4jdbc are used so that I can see how transaction is going such as commit / rollback.
Tags: guice