I have a service class like below. i call this "addPlayerToTeam" method from my controller class. This method has 3 operations:
1.control parameters and check data valid on my db (without transaction)
2.insert player to new team and create a history record (with transaction)
3.send notify to player for 'say hello' (without transaction)
But transactional method has a problem.
package com.thecodemakerz.transaction.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.thecodemakerz.transaction.domain.PlayerHistoryDto;
import com.thecodemakerz.transaction.domain.TeamPlayerDto;
import com.thecodemakerz.transaction.entity.Player;
@Service
@Slf4j
public class TeamPlayerServiceBestCase implements ITeamPlayerServiceBestCase {
@Autowired
private ITeamService teamService;
@Autowired
private IPlayerService playerService;
@Autowired
private IPlayerHistoryService historyService;
@Autowired
private IBildirimService bildirimService;
@Override
public Player addPlayerToTeam(TeamPlayerDto teamPlayerDto) {
Player player = addPlayerToTeamControl(teamPlayerDto);
player.setFkTeamId(teamPlayerDto.getFkTeamId());
player = addPlayerToTeamInsert(player);
sendNotifyAfterAddPlayerToTeam(player.getName());
return player;
}
@Override
public Player addPlayerToTeamControl(TeamPlayerDto teamPlayerDto) {
log.info("addPlayerToTeamControl start");
if (!teamService.existsById(teamPlayerDto.getFkTeamId())) {
throw new RuntimeException("Team not found");
}
Player player = playerService.findById(teamPlayerDto.getFkPlayerId());
if (player == null) {
throw new RuntimeException("Player not found");
}
log.info("addPlayerToTeamControl end");
return player;
}
@Override
@Transactional
public Player addPlayerToTeamInsert(Player player) {
log.info("addPlayerToTeamInsert start");
player = playerService.update(player);
PlayerHistoryDto historyDto = new PlayerHistoryDto();
historyDto.setFkPlayerId(player.getId());
historyDto.setFkTeamId(player.getFkTeamId());
historyService.addPlayerHistoryToNew(historyDto);
log.info("addPlayerToTeamInsert end");
return player;
}
@Override
public void sendNotifyAfterAddPlayerToTeam(String playerName) {
log.info("sendNotifyAfterAddPlayerToTeam start");
bildirimService.sendMail();
bildirimService.sendSms();
bildirimService.sendPush();
log.info("sendNotifyAfterAddPlayerToTeam end");
}
}
playerService.update method is below and not contains class level or method level transaction
@Override
public Player update(Player player) {
log.info("Player update işlemi yapılıyor");
if (player == null || !existsById(player.getId())) {
throw new RuntimeException("Player bulunamadı");
}
return playerRepo.save(player);
}
historyService.addPlayerHistoryToNew method is below and not contains class level but has method level transaction as @Transactional(propagation = Propagation.MANDATORY)
@Override
@Transactional(propagation = Propagation.MANDATORY)
public void addPlayerHistoryToNew(PlayerHistoryDto historyDto) {
log.info("addPlayerHistoryToNew işlemi yapılıyor");
update(historyDto);
insert(historyDto);
}
Following is the error result after running the method
2021-10-20 11:14:16.466 DEBUG 16016 --- [nio-8080-exec-5] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2021-10-20 11:14:16.467 INFO 16016 --- [nio-8080-exec-5] c.t.t.service.TeamPlayerServiceBestCase : addPlayerToTeamControl start
2021-10-20 11:14:16.468 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1505155637<open>)] for JPA transaction
2021-10-20 11:14:16.468 INFO 16016 --- [nio-8080-exec-5] c.t.transaction.service.TeamService : team existsById kontrolü
2021-10-20 11:14:16.468 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1505155637<open>)] for JPA transaction
2021-10-20 11:14:16.468 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.existsById]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2021-10-20 11:14:16.468 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@2d62109e]
2021-10-20 11:14:16.469 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2021-10-20 11:14:16.469 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1505155637<open>)]
2021-10-20 11:14:16.469 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2021-10-20 11:14:16.469 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Resuming suspended transaction after completion of inner transaction
2021-10-20 11:14:16.469 INFO 16016 --- [nio-8080-exec-5] c.t.transaction.service.PlayerService : player findById yapılıyor
2021-10-20 11:14:16.470 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1505155637<open>)] for JPA transaction
2021-10-20 11:14:16.470 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2021-10-20 11:14:16.470 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@78d5a812]
2021-10-20 11:14:16.471 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2021-10-20 11:14:16.471 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1505155637<open>)]
2021-10-20 11:14:16.471 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2021-10-20 11:14:16.471 INFO 16016 --- [nio-8080-exec-5] c.t.t.service.TeamPlayerServiceBestCase : addPlayerToTeamControl end
2021-10-20 11:14:16.471 INFO 16016 --- [nio-8080-exec-5] c.t.t.service.TeamPlayerServiceBestCase : addPlayerToTeamInsert start
2021-10-20 11:14:16.471 INFO 16016 --- [nio-8080-exec-5] c.t.transaction.service.PlayerService : Player update işlemi yapılıyor
2021-10-20 11:14:16.471 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1505155637<open>)] for JPA transaction
2021-10-20 11:14:16.471 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.existsById]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2021-10-20 11:14:16.471 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@2b46ef95]
2021-10-20 11:14:16.473 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2021-10-20 11:14:16.473 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1505155637<open>)]
2021-10-20 11:14:16.473 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2021-10-20 11:14:16.473 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1505155637<open>)] for JPA transaction
2021-10-20 11:14:16.473 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2021-10-20 11:14:16.473 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@a5a65bd]
2021-10-20 11:14:16.474 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2021-10-20 11:14:16.474 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1505155637<open>)]
2021-10-20 11:14:16.483 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2021-10-20 11:14:16.483 DEBUG 16016 --- [nio-8080-exec-5] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1505155637<open>)] for JPA transaction
2021-10-20 11:14:16.483 DEBUG 16016 --- [nio-8080-exec-5] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2021-10-20 11:14:16.484 ERROR 16016 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'] with root cause
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:362) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:574) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:361) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at com.thecodemakerz.transaction.service.PlayerHistoryService$$EnhancerBySpringCGLIB$$a78b3f88.addPlayerHistoryToNew(<generated>) ~[classes/:na]
at com.thecodemakerz.transaction.service.TeamPlayerServiceBestCase.addPlayerToTeamInsert(TeamPlayerServiceBestCase.java:64) ~[classes/:na]
at com.thecodemakerz.transaction.service.TeamPlayerServiceBestCase.addPlayerToTeam(TeamPlayerServiceBestCase.java:35) ~[classes/:na]
at com.thecodemakerz.transaction.service.TeamPlayerServiceBestCase$$FastClassBySpringCGLIB$$c8ddf51b.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at com.thecodemakerz.transaction.service.TeamPlayerServiceBestCase$$EnhancerBySpringCGLIB$$7e6a92e3.addPlayerToTeam(<generated>) ~[classes/:na]
at com.thecodemakerz.transaction.controller.PlayerTeamController.addPlayerToTeamBestCase2(PlayerTeamController.java:55) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
2021-10-20 11:14:16.485 DEBUG 16016 --- [nio-8080-exec-5] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2021-10-20 11:14:16.486 DEBUG 16016 --- [nio-8080-exec-5] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
BUT when I run the method as below, it works fine
@Override
@Transactional
public Player addPlayerToTeam(TeamPlayerDto teamPlayerDto) {
if (!teamService.existsById(teamPlayerDto.getFkTeamId())) {
throw new RuntimeException("İşlem yapılmak istenen Team bulunamadır");
}
Player player = playerService.findById(teamPlayerDto.getFkPlayerId());
if (player == null) {
throw new RuntimeException("İşlem yapılmak istenen Player bulunamadır");
}
player.setFkTeamId(teamPlayerDto.getFkTeamId());
Player savedPlayer = playerService.update(player);
PlayerHistoryDto historyDto = new PlayerHistoryDto();
historyDto.setFkPlayerId(teamPlayerDto.getFkPlayerId());
historyDto.setFkTeamId(teamPlayerDto.getFkTeamId());
historyService.addPlayerHistoryToNew(historyDto);
bildirimService.sendMail();
bildirimService.sendSms();
bildirimService.sendPush();
return savedPlayer;
}
Why am I getting an error in the proxy in the first example use? Does anyone know this? Can you help?
CodePudding user response:
When calling @Transactional
methods from within the same component the proxy is not involved, and no transaction is started therefore. The @Transactional
method has to be invoked from outside. (IMHO it's bad style to have several public methods that call each other.)