For more details, see http://www.developerscrappad.com/572/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-1-requires_new/
In an enterprise bean with container-managed transaction demarcation, the EJB container sets the boundaries of the transactions. You can use container-managed transactions with any type of enterprise bean: session, or message-driven. Container-managed transactions simplify development because the enterprise bean code does not explicitly mark the transaction’s boundaries. The code does not include statements that begin and end the transaction.
A transaction attribute can have one of the following values:
STICKY IMPORTANT HIGHLIGHT!!!:
** You can only bring out the effects of transaction attributes only when you call the method through a session bean instance and NOT through a direct method call. Even if your methods are within the same bean, you need to get the local instance of the same bean and call through its local interface instead of a direct method invoke. This message will appear in all the posts within this series as a REMINDER.
Scenario for TransactionAttributeType.REQUIRES_NEW to be In Action
TransactionAttributeType.REQUIRES_NEW is most suitable to be applied in the situation where the method’s transaction must not be affected by the transaction of the caller’s transaction.
One of the scenario that I could think of for methods to be annotated with REQUIRES_NEW to be in action is non-volatile audit trail (logging comments, remarks, actions by the user back into the database). Taking an example of a payment method to a 3rd party account from a banking module that deducts the amount of bank account when a transfer is successful (or nothing is performed is it fails), regardless if this transfer is successful or not (with a rollback), the logging facility would still need to be functional to log the status of the transaction and it must not be affect by the rollback of the transfer.
So I hope that clears the fog of transaction demacrate REQUIRES_NEW. If your method in a session bean needs to be completed without being affected by either commit or rollback from the calling session bean, REQUIRES_NEW is the way to go.
I’ll continue to the discussion on TransactionAttributeType.MANDATORY in the second part of this series. So for now, do enjoy your brew of codes.
Scenario for TransactionAttributeType.MANDATORY to be In Action
In my opinion, if your process is too lengthy to be contained in one method and if you need to split the codes into two or more sub-process methods, having the other sub-process methods to be annotated with MANDATORY is a good choice. And at the same time, if a method is annotated as MANDATORY, may not be suitable for direct invocation from external clients like web front-end (JSP, JSF, etc.) or remote clients.
Methods with TransactionAttributeType.MANDATOR could be run within methods that have transaction attributes such as REQUIRED, REQUIRES_NEW, MANDATORY and Supported (if only it is run within an already started transaction). In the contrary, it should not be invoked by methods with NOT_SUPPORTED and NEVER as it will not consist of a running transaction with MANDATORY to ride on.
In my next article, I’ll touch on both SUPPORTS AND NOT_SUPPORTED at the same time as they are quite related in certain context. Meanwhile, I do hope very much that this article could clear the fog of understanding the MANDATORY transaction attribute.
When to use TransactionAttributeType.SUPPORTS?
This is not absolute, but in my opinion and after going through myriads of projects with Java EE, I would annotate TransactionAttributeType.SUPPORTS on methods that query objects which the underlying data is consistently updated (constantly changing) and would always be involved in other transaction methods that carries Transaction Attribute Types like REQUIRED, MANDATORY or REQUIRES_NEW.
Query methods for changing data are well suited to be annotated with SUPPORTS because if the method only queries even without transaction, it could still return the data while not having to cause transaction overhead.
But on the contrary, if you annotate a method which performs persisting, merging or deletion of data in the database, use SUPPORTS wisely with discerning care.
When to use TransactionAttributeType.NOT_SUPPORTED?
TransactionAttributeType.NOT_SUPPORTED are better suited for methods that query objects which carries static data that won’t be expected to be changed or to be transactionally involved with other business transaction. It can be querying methods for statically permanent data like country list, region list, gender list, etc. Methods that query data to especially establish drop-down list options in the selection box of web-forms are very well suited to be annotated with NOT_SUPPORTED.
Annotating NOT_SUPPORTED in methods like these will greatly save applications from transaction overhead(s).
We have seen from the previous posts on REQUIRES_NEW and MANDATORY (REQUIRED included) that are mostly used for heavy transactionally orientated processes for data persisting, merging and deletion. But both SUPPORTS and NOT_SUPPORTED are just right for methods that performs data query instead of writing stuff back into the database.
Overall, for methods that are annotated with SUPPORTS, it can be part of a transaction context and it can run even without transaction, that makes it suitable for querying of constantly changing data. Whereas for methods that are annotated with NOT_SUPPORTED, it will just suspend any transaction if it is run within a transaction context, thus making it suitable to for querying any data which is non-changing, static and permanent.
I hope this article truly makes sense out of SUPPORTS and NOT_SUPPORTED transaction attribute types. Thank you for reading and happy coding.
When to use TransactionAttributeType.NEVER
In my opinion, a method should be annotated with TransactionAttributeType.NEVER if it only consist of logics that “NEVER” touches the database or any invocation of other methods which are transactional. Thus, the word NEVER.
For my past projects, I’ll annotate session bean methods with NEVER if they are only specifically involve in physical file reading and writing (I’ll skip the debates on EJB specs), raw number crunching, cropping/transformation/editing of an image, algorithms which serves an algorithmic purpose (funny, but it makes sense e.g. calculation of the upper and lower Bollinger bands for financial numbers) or even password encryption and decryption. These are just some of the examples of usage for methods with NEVER transaction attribute type. Notice that the above use cases didn’t touch any database layer and whatever the method processes, it is final and no correction when things go wrong. If you have specific use cases like this, NEVER is just the answer to your session bean method.
The benefits of using TransactionAttributeType.NEVER is it doesn’t involve any database transaction and thus it has limited overhead in usage of app server resources.
Transaction Attribute Types That “NEVER” Co-exists:
A session bean method that is annotated as NEVER is safe to be invoked by another session bean method that is annotated by TransactionAttributeType.NOT_SUPPORTED, as it will suspend any transaction before carrying out its business.
I hope that you have gain much by reading all of this 4 part series of transaction attributes. Knowing the behavior of the attribute type will just increase your knowledge, but knowing when to use them at the right time in the right places will do wonders in your application.