Rollback transactions in JAX-RS - java

I have a simple resource class that implements some POST method. How to rollback transaction if there was exceptions in my methods, and commit - if all is ok?
Is there a way to write this code once - not in every resource class that I have?

If you are using Spring, #Transactional will handle your scenario.
http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html

Using a dependency-injection will greatly simplify this. Using #Transactional or similar annotations around the methods where you want to commit/rollback transactions.
If you have to do this manually, you have basically two options:
do it manually for every operation
use the proxy pattern/decorator pattern and proxy/decorate all your classes that require transactions. Then in the proxy/decorator start the transaction, delegate to the target, and commit it after it returns. (this is how DI frameworks do it)

Related

Understanding Spring and "No EntityManager with actual transaction available"

I have a Spring Boot application with Hibernate, with a bunch of DAOs annotated with #Repository and Spring's #Transactional. Everything works fine. Then I decide to move common methods (persist, find, merge) to an AbstractDao. Writing operations (persist, merge) start throwing that No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call exception. I try adding #Transactional to AbstractDao, and contrary to my expectations, it fixes it.
Why is that so? I thought that since, unlike CGLIB, Spring uses interfaces instead of extending classes, it wouldn't work, and I would need to define an interface to declare instead of my DAOs. But I also guess that I'm mixing concepts of how Spring deals with dependency management and with transactions.
Can somebody provide an explanation of why does it work? Is there a better way of dealing with this problem?

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'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.

Rollback ORMapper Queries

We're using MyBatis (3.0.5) as our or-mapping tool (and I don't have any say-so over that!).
I've created a Response object that, through MyBatis, mapped to our [responses] database table (we use PostgreSQL).
Actually, the ormapping structure we use is as follows:
ResponseMapper.xml - this is the XML file where the PSQL queries are defined and mapped to the ResponseMapper.java** class and its methods
ReponseMapper.java - An interface used by MyBatis for executing the queries defined in the XML file (above)
ResponseDAO.java - An interface used for DI purposes (we use Spring)
ResponseDAOImpl.java - A concrete implementation of ResponseDAO that actually calls ResponseMapper methods; we use Spring to inject instances of this class into our application
So, to INSERT a new [responses] record into PostgreSQL, the code looks like this from the invoking component:
#Autowired
private ResponseDAO response;
public void doStuff()
{
int action = getAction();
response.setAction(action);
response.insert();
}
This set up works beautifully for us. However I am now trying to write a set of JUnit tests for the ResponseDAOImpl class, and I want to make sure that it is correctly executing queries to our PostgreSQL database.
As far as I can tell, there is no way to "mock" an entire database. So my only option (seemingly) is to have the test method(s) execute a query, check for success, and then roll it back regardless.
MyBatis doesn't seem to support this kind of rollback feature. I found this post off the mybatis-user mailing list on Old Nabble, but the poster was using Guice and his/her question seemed to be more about rolling back transactions through Guice.
If MyBatis doesn't support transactions/rollbacks (does it?!?!), then it seems like my only repireve would be if the PostgreSQL-JDBC driver supports these. I guess I could then try to configure my test methods so that they run the ResponseDAO.insert() method, and then manually try to rollback the transaction directly through the driver (sans MyBatis).
Does SO have any experience with this? Code samples? Tips? Best practices? Thanks in advance!
MyBatis allows rollbacks when working with an "SqlSession", the thing is your using the spring dependency injection piece, which automatically commits your transaction when the method completes.
You have a few options, among them
Inject a Mock of your dependencies. There is some rocking libraries to help with this. Like Mockito, here is a good question on Spring Mockito stuff. This will test your business logic in your java, but not your actual queries.
Commit your queries, and delete your data after the test runs. This is the approach we took, because it tests our database as well. You would obviously need a test instance of your database, which some people don't have.
You could try to provide your own test bindings for the classes that do the automatic commit in the MyBatis Spring Integration and override there behavior so that in the test environment the behavior is to rollback the query instead of committing. A similar approach was use in the Guice integration, and it is described here.
Not sure this is what you need, but org.apache.ibatis.session.SqlSession class has rollback() method which can be used to rollback.
Another approach is to use getConnection() method from the same class which will return javax.sql.Connection javax.sql.Connection class which also has commit() and rollback() methods.
Hope it helps.
Remis B

Which Aspect/Interceptor handles the #Transactional annotation

Does anyone know which class handles the #Transactional annotation? I am searching for the source code that creates the transaction, specifically.
I've done a deep code analysis for the #Transactional stuff here: http://doanduyhai.wordpress.com/2011/11/20/spring-transactional-explained/
Be carefull, this analysis only focus on JPA transaction. I did not consider datasources other than database but I guess the approach is similar
TransactionInterceptor handles the interception logic, but obviously with the assistance of a lot of other infrastructure classes. That's the best place to start, though. The transaction sync stuff is pretty fearsome when you start getting into the source code.
The processing of #Transactional, and its parsing into the neutral transaction descriptor object model, is done by AnnotationTransactionAttributeSource.

Categories