0

I am using spring jpa transactions in my project.One Case includes inserting a data in a synchronized method and when another thread accesses it the data is not updated.My code is given below :

public UpdatedDTO parentMethod(){
  private UpdatedDTO updatedDTO = getSomeMethod();
  childmethod1(inputVal);
  return updatedDTO;
}

@Transactional
public synchronized  childmethod1(inputVal){
 //SomeCodes

 //Place where update takes place
 TableEntityObject obj = objectRepository.findByInputVal(inputVal);
 if(obj == null){
    childMethod2(inputVal);
  }

}

@Transactional
public void childMethod2(inputVal){

//Code for inserting
TableEntityObject obj = new TableEntityObject();
obj.setName("SomeValue");
obj.setValueSet(inputVal);
objectRepository.save(obj);
}

Now if two threads access at the same time and if first thread completes childmethod2 and childmethod1 and without completing parentMethod() after that if second thread comes to the childMethod1() and checks if data exists,the data is null and is not updated by first thread.I have tried many ways like

@Transactional(propagation = Propagation.REQUIRES_NEW)
public synchronized  childmethod1(inputVal){
 //SomeCodes

 //Place where update takes place
 TableEntityObject obj = objectRepository.findByInputVal(inputVal);
 if(obj == null){
    childMethod2(inputVal);
  }

} 

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void childMethod2(inputVal){

//Code for inserting
TableEntityObject obj = new TableEntityObject();
obj.setName("SomeValue");
obj.setValueSet(inputVal);
objectRepository.save(obj);
}

also tried taking off @transactional in the childMethod1() but nothing works out.I know im doing something wrong here , but couldnt figure out where and what exactly i am doing wrong.Can anyone help me out with this

2 Answers2

0

@Transactional is resolved using proxies on spring beans. It means it will have no effect if your method with @Transactional is called from the same class. Take a look at Spring @Transaction method call by the method within the same class, does not work?

The easiest would be moving those methods into separate service.

Community
  • 1
  • 1
hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50
0

Typical checklist I follow in cases like these :

  1. If Java based configuration then make sure @EnableTransactionManagement annocation is present in the class containing the @Configuration annotation
  2. Make sure the transactionManager bean is created, again this should be mentioned in the configuration class.
  3. Use of @Transactional annocatio over the method which is calling the repository, typically a class in the DAO layer
  4. Adding the @Service annotation for the class which is invoking the methods in the repository

Nice blog which explains the Transaction configuration with JPA in depth --> http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/68954

Srikanta
  • 1,145
  • 2
  • 12
  • 22