On services and #Transactional - java

If I have a service class which calls three other service classes in a row, and each of those sub-services has to deal with a DAO object at some point, how can I make so that the wrapper service wraps them all into a single transaction? Will it be as simple as annotating the wrapper with #Transactional? What if the DAO is already marked as #Transactional?

The default transaction propagation in Spring framework is REQUIRED, which means that the transaction is created if it does not already exist or the code joins existing one:
Support a current transaction, create a new one if none exists. Analogous to EJB transaction attribute of the same name.
This is the default setting of a transaction annotation.
This means that if you wrap calls to three transactional methods in a single transactional method, they will all run within a single transaction. Just like that.
See also:
What is the right way to use spring MVC with Hibernate in DAO, sevice layer architecture

If you annotate the outer service as #Transactional and your DAOs are also #Transactional and called by the service they will by default join the outer transaction as you're hoping.

this is actually a question about nested transaction (http://en.wikipedia.org/wiki/Nested_transaction). with spring, (assume you are using version 3 and annotation), REQUIRED is default for transaction mode. If you set this model for your service methods, all methods wrapped by your "wrapper" service will use the host transaction, which means they will run in same transaction.

Related

Example of Propagation in spring data JPA

I am trying to understand the propagation attribute of #Transactional annotation in Spring Data JPA. I have read enough theory. But I do not understand(nor can I find anywhere on internet) the real-life scenario where I need to use the PROPAGATION_REQUIRED in place of PROPAGATION_REQUIRES_NEW. I understand the theory that PROPAGATION_REQUIRED can utilize the existing transaction and PROPAGATION_REQUIRES_NEW will start a new transaction each time. But I could not understand two things -
How does it matter to me as a programmer? or in which used cases one is preferred over other?
Is the "TRANSACTION" we are talking about is a spring transaction or a database transaction
In Spring, if a method that is annotated with #Transactional calls another method annotated with #Transactional, the transaction is started at the beginning of the first method and commited after the second method is finished.
Requiring a new transaction can be helpful, if you have a sequence of methods that are transactional but you want to commit a transaction half way through the sequence.
Or maybe you have a method that should always open it's own transaction and you want to make sure it does so, even if it is called by another transactional method.

JTA for single database

I am just learning JTA and can't understand if I should use it if I have only one database. Currently I use hibernate 5 as JPA provider and if I need to use one transaction between methods I just pass EntityManager as argument.
However, I don't like this method as I need to remember if transaction is opened or not. I would like to find any library that will help me to control transactions (but without Spring) in SE environment. So, should I use JTA in my situation or should I use something different?
Normally when talking about JTA , it refers to the distributed transaction across multiple systems (e.g. across two databases , one database and one JMS compliant message broker). If you only have one database , it is not necessary to use JTA transaction although it should also work. Instead, use a local transaction for one database which should theoretically faster than using JTA transaction.
On the other hands , if you are just talking about #Transactional defined in the JTA , which allow you to declaratively control the transaction boundary by annotating it on a method and without passing the EntityManager between methods , you should look into which frameworks support it.
Under the cover , a proxied EntityManager is injected into different classes such that when it is invoked , it will get the actual EntityManager from the ThreadLocal. So every class in the same thread will get the same EntityManager which prevent you from passing the EntityManager around the methods. A new EntityManager instance will be set to the ThreadLocal just before the #Transactional method is executed using some sort of AOP technique.
Please note that #Transcational is nothing to do with the underlying transaction is JTA or local transaction. It should work for both transaction type.
I would use a framework that support #Transactional such as Spring , Quarkus or Micronaut etc , and configure Hibernate to use local transaction but not JTA transaction for single database.

Java service transaction practice

We use to define transaction using #Transactional annotation or else way to défine transactions.
We also use to define a transaction on a service or specificaly on its methods.
Recently, a colleague suggested no to set transaction on services but on the caller (remote controller for angular, batch, IHM controller like jsf...).
I found this approach interestings.
What do you think about this ?
You probably need both. Services should be transactional, or at least SUPPORTS for reads / selects. But, in the web controller or other top-level layer you also need transactions if you call more than one service.
Note, however, that if you controllers are concrete classes, you are going to need to use AOP or other proxy mechanisms to wrap functions in a transactional layer. The other option is to just autowire in a TransactionTemplate into your controllers and do TX management manually where you need it.
Obviously the TX template approach means you have to be careful to actually use it when needed. With the proxy approach you can just make every controller function transactional. But the overhead may be more than you want if there are only a few functions that make more than one service call.

Spring JTATransactionManager fails to bind Hibernate and JDBC in a single session

I use JTATransactionManager to manage Transactions. One piece of code that I want to wrap with Spring's #Transactional annotation has 2 database calls - one using Hibernate SessionFactory and another a plain JDBC. Both use the same dataSource. Hence, I expect both to be bound by the same Transaction.
But it does not look like one Transaction is used. Instead each opens its own Transaction. What could be the reason for this. ? How do I make sure to use a single Transaction to bind both these operations. ?
I can provide configuration and code if needed.
Make sure in both of your database calls, you use propagation as Propagation.NESTED as
#Transactional(propagation=Propagation.NESTED)
and in the wrapper method, you mention Propagation.REQUIRED orPropagation.REQUIRED_NEW` as
#Transactional(propagation=Propagation.REQUIRED)
or
#Transactional(propagation=Propagation.REQUIRED_NEW)
By doing this, you mention that both DB calls will inherit the transaction boundary of the wrapper method.

Spring's JdbcTemplate and Transactions

When using JdbcTemplate, do I need to explicitly configure transactions?
My code layout looks like the following:
I will have a UserDao that will be injected into my UserService, and then my Controllers will make calls on methods in my UserService.
I want to keep things as simple as possible transaction wise, and I don't need multiple database calls to span a transaction.
By default, do I have to do anything in my configuration file or use a #Transaction annotation anywhere?
Now say in my controller I need to make 2 calls on my userService and accountService, could I explicitly wrap it in a transaction somehow?
userService.updateUser(user);
accountService.updateXXX(...);
Yes, JdbcTemplate is not a substitute for transaction management. You still benefit from database transactions, so userService.updateUser will operate in a database transaction, but if accountService.updateXXX fails, userService.updateUser will not rollback.
If you don't want to use AOP, you can use TransactionTemplate instead. See programmatic transaction management in the Spring Reference Documentation.
One pattern I've seen before is for the MVC controller class to invoke a business service, which encapsulates the operation. The method of the business class could then be annotated #Transactional.
If your controller wants to do several things with users and accounts and have all that happen within one transaction, then you should have a service with one method that does all that stuff. Creating one service per DAO is not a great idea, because you end up with do-nothing wrappers around DAOs and processing will be slow because the database will have to create a separate transaction for each call to a DAO, you're making it do a lot more work than it should have to.
The service should provide functionality to the controller or whoever else is calling it. I try to create services with the idea that the service provides specific functions useful to a certain type of user.

Categories