#Transactional in a service class with no call to database - spring

When a service class has no implementation of Jpa repository ,My understanding is that it is wrong to annotate it with Transactional, for example this service class with should not have #Transactional
#Service
public class BillingAddressServiceImpl implements BillingAddressService {
public BillingAddress setByUserBilling(UserBilling userBilling, BillingAddress billingAddress) throws DataAccessException
{
billingAddress.setBillingAddressName(userBilling.getUserBillingName());
billingAddress.setBillingAddressStreet1(userBilling.getUserBillingStreet1());
billingAddress.setBillingAddressStreet2(userBilling.getUserBillingStreet2());
billingAddress.setBillingAddressCity(userBilling.getUserBillingCity());
billingAddress.setBillingAddressState(userBilling.getUserBillingState());
billingAddress.setBillingAddressCountry(userBilling.getUserBillingCountry());
billingAddress.setBillingAddressZipCode(userBilling.getUserBillingZipCode());
return billingAddress;
}
}

The Transactional annotation stands for declaring the database transaction handling of Spring bean methods.
Since your service method is not working with the database it makes no sense to declare a transaction handling.

Transactional annotations are only used with method or classes that makes calls to database,one of the uses of transactional annotation is rollback - which means when we make call to a database there would be a recording of the intermidiate state between the successful call and its original state, this is so that in the case of a failed call the system does not crash but is able to return to its original state

Related

How to handle Spring transactions inside coroutines?

It is known that Spring transactions are tied to threads: there are thread locals specific for an ongoing transaction. And transactions know nothing about coroutine context. So what if I would like to call a #Transactional method from inside a coroutine: is it safe?
Imagine we have a method inside JobProcessor bean processing a job list. Each job is processed inside async{}. And I would like to update DB after every successful or failed processing using #Transactional methods of bean JobService.
class JobProcessor {
fun process(jobs: List<MyJob>) =
jobs.map { job ->
async {
try {
....//processing
jobService.success(job)
} catch (t: Throwable) {
jobService.failure(job)
}
}
}
class JobService {
#Transactional
fun success(job: MyJob) {...}
#Transactional
fun failure(job: MyJob) {...}
}
First, please keep in mind that annotating bean methods with #Transactional will not suffice - make sure you enabled declarative transaction handling, e.g. by adding #EnableTransactionManagement to a #Configuration class or by using <tx-annotation-driven /> in XML config.
Regarding your question: There will only be a transactional context while executing Spring bean methods annotated with #Transactional when they are being invoked from a Spring bean outside of their containing class! Declarative transactions in Spring rely on AOP proxy classes being created for the #Transactional annotated classes by Spring. At runtime if a Spring bean A calls a #Transactional method on a Spring bean B, the call will be intercepted by an AOP proxy that transparently spawns a transaction, calls the original method of Spring bean B and commits or rollbacks this transaction afterwards.
Remember: Only external method calls that come in through the proxy will be intercepted – any self-invocation calls, as in your example this.process() calling #Transactional methods this.success() or this.failure() will not start any transaction – even if the method is annotated with #Transactional.

Whether and When Spring Lock Table if Method Annotated with Transactional

This question comes from that, if I have a methodA, and methodB in classA like below
public class classA {
public void methodA() {
// some code
...
// time to deal with db
methodB();
}
#Transactional
public void methodB() {
// insert a record
throw new RuntimeException("testing");
}
}
In classB Directly call methodA, there will be no transactional effect on methodB(this is to say spring will not rollback the insert operation even RuntimeException occurred).
When I move the #Transactional from methodB to methodA, and call methodA again, the #Transactional annotation works.
However, if I have really a lot of work to do in methodA, will spring lock the table during the total execution time?
Well, I will add a new class(i.e. classC) and move methodB(annotated with Transactional) to the new class as workaround.
It is the limitation of Springs AOP that #Transactional will not have effect if the method is called within the same class.
Refer to #Transactional method called from another method doesn't obtain a transaction
Spring doesn't handle transaction by itself. #Transactional annotation lets Spring's proxy class to inject transaction begin and commit/rollback methods around your original method.
Proxy wrapper will only be called if you invoke annotated method from outside the classes. Local method call will not use proxy class. So, call from method A to method B will not use transactional features.
Secondly, Spring will simply delegate the transaction handling to underlying database driver. Whether your table acquires a lock or not will be determined by your driver documentation and (atomicity and isolation level) settings.

Spring managed transactions #Transactional annotation

Propagation setting is REQUIRED.
#Transactional(propagation = Propagation.REQUIRED)
Transaction is read/write.
In which scenario those are used? Please give me explain with example
Spring transaction default is
#Transactional(propagation = Propagation.REQUIRED)
So you do not need to specify the propagation property.
So, What does it mean by #Transactional annotation for a spring component ?
Spring framework will start a new transaction and executes all the method and finally commit the transaction.
But If no transaction is exists in the application context then spring container will start a new transaction.
If more than one method configured as Propagation.REQUIRED then transactional behavior assigned in a nested way to each method in logically but they are all under the same physical transaction.
So, What is the result ?
The result is if any nested transaction fail, then the whole transaction will fail and rolled back (do not insert any value in db) instead of commit.
Example:
#Service
public class ServiceA{
#Transactional(propagation = Propagation.REQUIRED)
public void foo(){
fooB();
}
#Transactional(propagation = Propagation.REQUIRED)
public void fooB(){
//some operation
}
}
Explanation :
In this example foo() method assigned a transactional behavior and inside foo() another method fooB() called which is also transactional.
Here the fooB() act as nested transaction in terms of foo(). If fooB() fails for any reason then foo() also failed to commit. Rather it roll back.
This annotation is just to help the Spring framework to manage your database transaction.
Lets say you have a service bean that writes to your database and you want to make sure that the writing is done within a transaction then you use
#Transactional(propagation = Propagation.REQUIRED)
Here is a small example of a Spring service bean.
#Service
class MyService {
#Transactional(propagation = Propagation.REQUIRED)
public void writeStuff() {
// write something to your database
}
}
The Transactional annotation tells Spring that:
This service method requires to be executed within a transaction.
If an exception gets thrown while executing the service method, Spring will rollback the transaction and no data is written to the database.

Service layer and dao layer in java ee EJBs

Question: Can anyone, in context to Java EE and EJBs, show a specific DAO class (or more than one) that has two different methods. and a service class that calls those 2 methods in ONE transactional boundary with roll back?
I have an EJB but I want to use it as service layer like in spring #Transactional methods.
1) is it a good idea ?
2) how can I make many dao method calls in one "transaction" in one method? I think I have to make some strategy on transaction.begin() and . comit()? can anyone show a code example please?
Some of the main advantages would be that:
a- all the small immutable DAO transactions will be committed in "one go" in the single database connection made (in single transactional boundries)
b- If say I have 4 dao calls in server and the third one fails, since its one transactional boundry, I can do roll backs.
c- my immutable DAO methods will be re-usable in many other places.
Java EE example:
import com.....entities.Users;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
#Stateless
public class UsersBean {
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
public Users sayHello() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("CommunityPU");
EntityManager em = emf.createEntityManager();
Users user = em.find(Users.class, 1);
em.close();
emf.close();
return user;
}
}
vs. spring:
#Controller
class MyControllerClass {
#RequestMapping...
method(){
ServiceCall()...
//put something to modelAndView object here and redirect to jsp page.
return "home"; // this will redirect data to home.jsp
}
}
//Service class /////////
#Service
class MyServiceClass{
#Transactional
SomeServiceMethod(){
DaoMethod();
SomeMoreDaoMethods();
}
}
//Dao class ////////
#Autowired
EntityManager em;
#Repository
class MyDaoClass{
DaoMethdon(){em.find(...)}
}
/view/myjsps.jsp path to view directory set in spring.xml
Edit - 1 (cross question to the answer for further clarification)
1) will the DAO itself be an EJB? or EJBs are strict service layers that call other immutable dao methods (that reside in dao classes).
2) we wont use entitymanager in EJBs but in Daos. correct?
3) how about using #Transactional (Until Java EE 7 only EJB where transactional and the #Transactional annotation didn't exist.) or #TransactionAttribute.
4) what if we use non #stateless. Then it wont manage the daos in one transactional boundry not use roll backs?
RND links:
https://stackoverflow.com/a/17840851
http://docs.oracle.com/javaee/5/tutorial/doc/bncij.html
Is is a good idea?
Yes. That's what EJBs are for, basically.
how can I make many dao method calls in one "transaction" in one method?
You just do it:
#Stateless
public class MyService {
#Inject
private FirstDao firstDao;
#Inject
private SecondDao secondDao;
// stateless EJBs are transactional by defaults.
public void doStuff() {
firstDao.doSomething();
secondDao.doSomethingElse();
}
}
EJBs are transactional by default. You don't need to start and commit transactions programmatically. The container does that for you: if any of the 2 DAO calls throws a runtime exception, the transaction will roll back. Otherwise, it will commit.
Also note that the entity manager shouldn't be used by your service EJB. That's what DAOs are for: deal with persistence. So the DAOs should be the one using the entity manager:
public class FirstDao {
#PersistenceContext
private EntityManager em;
...
}
Regarding your last questions:
DAOs can be EJBs themselves, but it's not necessary, since transactions are normally demarcated by the service layer.
I already answered that. Of course The Data access objects are the ones who must use the EntityManager, since their job is to handle persistence, and the EntityManager is used to access the database.
Do it the way you want. What's important is that your services should be transactional, whatever the way you make them transactional. Transactional was introduced to remove the need for EJBs and have transactional CDI beans. If you prefer it that way, then fine.
Small note: an immutable method doesn't make sense. Something (like an object) is immutable when its state never changes. Methods don't have state.

Which layer is most suitable to handle transaction in Spring 3 Mybatis integrated application?

Currently I develop Spring 3, Mybatis and Struts2 integrated application using MVC architecture.But I face some difficulties to handle transaction in my application.I use Spring Transaction in my service layer,likes this
Service Layer
#Service("MyService")
#Transactional
public class MyServiceImpl implements IMyService {
#Transactional(readOnly=false)
public void myMethod() {
}
}
My question is "Should I use Spring Transaction in my data access layer instead of service layer?" likes this
Data Access Layer
#Repository("MyDAO")
public class MyDAO implements IMyDAO {
#Transactional(readOnly=false)
public void myMethod() {
}
}
If your calling each DAO method through the Service layer than make the service layer transactional. If you call some DAO methods independent of the Service layer than the DAO methods will need to be transactional. You could also make both transactional since Spring will propogate the transactions in both layers, meaning if you call a Service method that is transactional which calls a transactional DAO method, they will share the same transaction.

Resources