Aviral Ahuja
Aviral Ahuja

Reputation: 215

TransactionRequiredException in SpringBoot

my controller is as follow:

 @GetMapping("/groupByCourse")
    public Reply getStudentsCountByCourse(){
        Reply reply=new Reply();
        reply.setData(service.getStudentsCountByCourse());
        return reply;
    }

and Service is:-

public List getStudentsCountByCourse()  {
            List students=new ArrayList<>();

            students=studentCourseRepo.findCountStudentByCourse();

            getCourseCountByStudent();

        return students;
    }
    @Transactional(Transactional.TxType.REQUIRES_NEW)
   public List getCourseCountByStudent()  {
            List students=new ArrayList<>();

            students=studentCourseRepo.findCountCourseByStudent();


        return students;
    }

and repository is :-

@Repository
public interface StudentCourseRepo  extends CrudRepository<StudentCourseTbl, StudentCourseTblPK> {

    @Query(value = "select  sc.studentCourseTblPK.courseId,count(sc.studentCourseTblPK.studentId) from StudentCourseTbl sc group by sc.studentCourseTblPK.courseId")
    List findCountStudentByCourse();

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query(value = "select  s.id,s.name,count(sc.studentCourseTblPK.courseId) from StudentCourseTbl sc  right join StudentsTbl s on sc.studentCourseTblPK.studentId=s.id group by s.id")
    List findCountCourseByStudent();
}

I am already using @Transactional(Transactional.TxType.REQUIRES_NEW) in my service method that execute the query with Pessimistic_write lock but still i am getting TransactionRequiredException even after transaction mode is set to requires new.I know i can make the code work by using @Transactional annotation on my getStudentsCountByCourse method but i want to know the reason why it doesnot work currently.

I am using springboot version 2.1.7.Release with mysql as database

Upvotes: 0

Views: 456

Answers (1)

Sukhpal Singh
Sukhpal Singh

Reputation: 2288

This is a known limitation of Spring default CGLIB proxies. Since the transactional behavior is based on proxies, a method of the target object calling another of its method won’t lead to transactional behavior even though the latter method is marked as transactional.

This can be avoided by weaving the transactional behavior inside the bytecode instead of using proxies i.e. using AspectJ.

You can read more about spring transaction management here Method visibility and @Transactional

Upvotes: 1

Related Questions