ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @Transactional 제대로 알고 쓰기
    Spring 2021. 11. 18. 02:23

    @Transactional 을 꼭 붙여야 하나? 왜 붙여야 하지? 라는 의문들을 가지신 분들이 분명히 있을 겁니다!

    그래서 오늘은 아주 간단한 Sample 코드를 통해서 @Transactional 을 붙였을 때와 붙이지 않았을 때 어떤 이들이 벌어지는지 확인해 볼께요!

    그리고 DB 테이블이 데이터가 들어가는지 들어가지 않는지 뿐만 아니라, Spring이 트랜잭션을 어떤식으로 처리하는지  로그까지 확인해 보도록 하겠습니다.

    로그는 org.springframework.jdbc 패키지 경로를 줘서 확인하면 됩니다. 참고로 mybatis를 사용했습니다.

    테스트 내역은 아래와 같습니다.

    • insert(insert 만 테스트 했지만, commit 관련해서는 update, delete 도 동일합니다.)
      • @Transactional 이 없는 경우
      • @Transactional(rollbackFor = Exception.class) 인 경우
      • @Transactional(readonly = true) 인 경우
      • @Transactional 만 있는 경우
    • select
      • @Transactional 이 없는 경우
      • @Transactional(readonly = true) 인 경우
      • @Transactional(rollbackFor = Exception.class) 인 경우
      • @Transactional 만 있는 경우

     

     

     

    @Transactional 이 없는 경우

        public void insertTest1() throws Exception {
    
            log.debug(">>>>>>>>>> NONE Transactional FORCE_THROW!!!!!");
            
            scheduleRepository.insertTest();
    
            if (FORCE_THROW) throw new Exception(">>>>>>>>>> NONE Transactional FORCE_THROW!!!!!");
    
            scheduleRepository.insertTest();
        }

    output log

    2021-11-18 01:53:39.777 [http-nio-9999-exec-3] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> NONE Transactional FORCE_THROW!!!!!
    2021-11-18 01:53:39.778 [http-nio-9999-exec-3] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
    2021-11-18 01:53:39.793 [http-nio-9999-exec-3] DEBUG c.b.a.a.m.s.r.S.insertTest - ==>  Preparing: insert into dummy_test (token) values ('asdf')
    2021-11-18 01:53:39.794 [http-nio-9999-exec-3] DEBUG c.b.a.a.m.s.r.S.insertTest - ==> Parameters: 
    2021-11-18 01:53:39.807 [http-nio-9999-exec-3] DEBUG c.b.a.a.m.s.r.S.insertTest - <==    Updates: 1
    2021-11-18 01:53:39.809 [http-nio-9999-exec-3] ERROR c.b.a.a.c.r.GlobalExceptionHandler - handleException
    java.lang.Exception: >>>>>>>>>> NONE Transactional FORCE_THROW!!!!!
    	at service.ScheduleServiceImpl.insertTest1(ScheduleServiceImpl.java:28)
    	at service.ScheduleServiceImpl$$FastClassBySpringCGLIB$$635d091c.invoke(<generated>)
    	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687)
    	at service.ScheduleServiceImpl$$EnhancerBySpringCGLIB$$7d065a04.insertTest1(<generated>)
    	at contorller.ScheduleController.test1(ScheduleController.java:22)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    	at java.lang.Thread.run(Thread.java:748)
    2021-11-18 01:53:39.813 [http-nio-9999-exec-3] WARN  o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [java.lang.Exception: >>>>>>>>>> NONE Transactional FORCE_THROW!!!!!]

    결과

    1건 등록 됨

    @Transactional(rollbackFor = Exception.class) 이 있는 경우

        @Transactional(rollbackFor = Exception.class)
        public void insertTest2() throws Exception {
    
            log.debug(">>>>>>>>>> NONE Transactional FORCE_THROW!!!!!");
            scheduleRepository.insertTest();
    
            if (FORCE_THROW) throw new Exception(">>>>>>>>>> OK Transactional FORCE_THROW!!!!!");
    
            scheduleRepository.insertTest();
        }

    output log

    2021-11-18 01:58:22.329 [http-nio-9999-exec-6] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [service.ScheduleServiceImpl.insertTest2]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.Exception
    2021-11-18 01:58:22.338 [http-nio-9999-exec-6] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1903766913 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] for JDBC transaction
    2021-11-18 01:58:22.338 [http-nio-9999-exec-6] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1903766913 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] to manual commit
    2021-11-18 01:58:22.345 [http-nio-9999-exec-6] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> NONE Transactional FORCE_THROW!!!!!
    2021-11-18 01:58:22.346 [http-nio-9999-exec-6] DEBUG c.b.a.a.m.s.r.S.insertTest - ==>  Preparing: insert into dummy_test (token) values ('asdf')
    2021-11-18 01:58:22.346 [http-nio-9999-exec-6] DEBUG c.b.a.a.m.s.r.S.insertTest - ==> Parameters: 
    2021-11-18 01:58:22.353 [http-nio-9999-exec-6] DEBUG c.b.a.a.m.s.r.S.insertTest - <==    Updates: 1
    2021-11-18 01:58:22.353 [http-nio-9999-exec-6] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction rollback
    2021-11-18 01:58:22.353 [http-nio-9999-exec-6] DEBUG o.s.j.d.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [HikariProxyConnection@1903766913 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e]
    2021-11-18 01:58:22.379 [http-nio-9999-exec-6] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1903766913 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] after transaction
    2021-11-18 01:58:22.381 [http-nio-9999-exec-6] ERROR c.b.a.a.c.r.GlobalExceptionHandler - handleException
    java.lang.Exception: >>>>>>>>>> OK Transactional FORCE_THROW!!!!!
    	at service.ScheduleServiceImpl.insertTest2(ScheduleServiceImpl.java:40)
    	at service.ScheduleServiceImpl$$FastClassBySpringCGLIB$$635d091c.invoke(<generated>)
    	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    	at service.ScheduleServiceImpl$$EnhancerBySpringCGLIB$$7d065a04.insertTest2(<generated>)
    	at contorller.ScheduleController.test2(ScheduleController.java:27)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    	at java.lang.Thread.run(Thread.java:748)
    2021-11-18 01:58:22.383 [http-nio-9999-exec-6] WARN  o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [java.lang.Exception: >>>>>>>>>> OK Transactional FORCE_THROW!!!!!]

    결과

    1건도 insert 되지 않음

    @Transactional(readonly = true) 인 경우

        @Transactional(readOnly = true)
        public void insertTest3() throws Exception {
    
            log.debug(">>>>>>>>>> readOnly Transactional FORCE_THROW!!!!!");
            scheduleRepository.insertTest();
    
            if (FORCE_THROW) throw new Exception(">>>>>>>>>> READONLY Transactional FORCE_THROW!!!!!");
    
            scheduleRepository.insertTest();
        }

    output log

    2021-11-18 02:01:15.842 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [ScheduleServiceImpl.insertTest3]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
    2021-11-18 02:01:15.850 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@864307427 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] for JDBC transaction
    2021-11-18 02:01:15.850 [http-nio-9999-exec-8] DEBUG o.s.jdbc.datasource.DataSourceUtils - Setting JDBC Connection [HikariProxyConnection@864307427 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] read-only
    2021-11-18 02:01:15.850 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@864307427 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] to manual commit
    2021-11-18 02:01:15.860 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> readOnly Transactional FORCE_THROW!!!!!
    2021-11-18 02:01:15.860 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.r.S.insertTest - ==>  Preparing: insert into dummy_test (token) values ('asdf')
    2021-11-18 02:01:15.861 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.r.S.insertTest - ==> Parameters: 
    2021-11-18 02:01:16.023 [http-nio-9999-exec-8] DEBUG o.s.j.support.SQLErrorCodesFactory - Looking up default SQLErrorCodes for DataSource [com.zaxxer.hikari.HikariDataSource@4d4d6133]
    2021-11-18 02:01:16.026 [http-nio-9999-exec-8] DEBUG o.s.j.support.SQLErrorCodesFactory - SQL error codes for 'MySQL' found
    2021-11-18 02:01:16.026 [http-nio-9999-exec-8] DEBUG o.s.j.support.SQLErrorCodesFactory - Caching SQL error codes for DataSource [com.zaxxer.hikari.HikariDataSource@4d4d6133]: database product name is 'MySQL'
    2021-11-18 02:01:16.026 [http-nio-9999-exec-8] DEBUG o.s.j.s.SQLErrorCodeSQLExceptionTranslator - Unable to translate SQLException with Error code '0', will now try the fallback translator
    2021-11-18 02:01:16.027 [http-nio-9999-exec-8] DEBUG o.s.j.s.SQLStateSQLExceptionTranslator - Extracted SQL state class 'S1' from value 'S1009'
    2021-11-18 02:01:16.028 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction rollback
    2021-11-18 02:01:16.028 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [HikariProxyConnection@864307427 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e]
    2021-11-18 02:01:16.041 [http-nio-9999-exec-8] DEBUG o.s.jdbc.datasource.DataSourceUtils - Resetting read-only flag of JDBC Connection [HikariProxyConnection@864307427 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e]
    2021-11-18 02:01:16.041 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@864307427 wrapping com.mysql.cj.jdbc.ConnectionImpl@7554837e] after transaction
    2021-11-18 02:01:16.043 [http-nio-9999-exec-8] ERROR c.b.a.a.c.r.GlobalExceptionHandler - handleException
    org.springframework.dao.TransientDataAccessResourceException: 
    ### Error updating database.  Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    ### The error may exist in repository/ScheduleRepository.xml
    ### The error may involve defaultParameterMap
    ### The error occurred while setting parameters
    ### SQL: insert into dummy_test (token) values ('asdf')
    ### Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    ; Connection is read-only. Queries leading to data modification are not allowed; nested exception is java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:110)
    	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:88)
    	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
    	at com.sun.proxy.$Proxy94.insert(Unknown Source)
    	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:271)
    	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62)
    	at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152)
    	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
    	at com.sun.proxy.$Proxy128.insertTest(Unknown Source)
    	at service.ScheduleServiceImpl.insertTest3(ScheduleServiceImpl.java:51)
    	at service.ScheduleServiceImpl$$FastClassBySpringCGLIB$$635d091c.invoke(<generated>)
    	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    	at ScheduleServiceImpl$$EnhancerBySpringCGLIB$$7d065a04.insertTest3(<generated>)
    	at contorller.ScheduleController.test3(ScheduleController.java:32)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    	at java.lang.Thread.run(Thread.java:748)
    Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:127)
    	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
    	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:87)
    	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:61)
    	at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:335)
    	at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
    	at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59)
    	at com.sun.proxy.$Proxy178.execute(Unknown Source)
    	at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47)
    	at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
    	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
    	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
    	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
    	... 69 common frames omitted
    2021-11-18 02:01:16.044 [http-nio-9999-exec-8] WARN  o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [org.springframework.dao.TransientDataAccessResourceException: 
    ### Error updating database.  Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    ### The error may exist in /repository/ScheduleRepository.xml
    ### The error may involve defaultParameterMap
    ### The error occurred while setting parameters
    ### SQL: insert into dummy_test (token) values ('asdf')
    ### Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    ; Connection is read-only. Queries leading to data modification are not allowed; nested exception is java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed]

    결과

    1건도 등록되지 않음

    아무 속성 없이 @Transactional 만 붙인 경우

        @Transactional
        public void insertTest4() throws Exception {
    
            log.debug(">>>>>>>>>> Transactional FORCE_THROW!!!!!");
            scheduleRepository.insertTest();
    
            if (FORCE_THROW) throw new Exception(">>>>>>>>>> READONLY Transactional FORCE_THROW!!!!!");
    
            scheduleRepository.insertTest();
        }

    output log

    2021-11-18 02:04:02.484 [http-nio-9999-exec-1] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
    2021-11-18 02:04:02.484 [http-nio-9999-exec-1] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
    2021-11-18 02:04:02.495 [http-nio-9999-exec-1] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 11 ms
    2021-11-18 02:04:02.525 [http-nio-9999-exec-1] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [ScheduleServiceImpl.insertTest4]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
    2021-11-18 02:04:02.535 [http-nio-9999-exec-1] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1739907345 wrapping com.mysql.cj.jdbc.ConnectionImpl@28ddd184] for JDBC transaction
    2021-11-18 02:04:02.541 [http-nio-9999-exec-1] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1739907345 wrapping com.mysql.cj.jdbc.ConnectionImpl@28ddd184] to manual commit
    2021-11-18 02:04:02.553 [http-nio-9999-exec-1] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> Transactional FORCE_THROW!!!!!
    2021-11-18 02:04:02.567 [http-nio-9999-exec-1] DEBUG c.b.a.a.m.s.r.S.insertTest - ==>  Preparing: insert into dummy_test (token) values ('asdf')
    2021-11-18 02:04:02.588 [http-nio-9999-exec-1] DEBUG c.b.a.a.m.s.r.S.insertTest - ==> Parameters: 
    2021-11-18 02:04:02.600 [http-nio-9999-exec-1] DEBUG c.b.a.a.m.s.r.S.insertTest - <==    Updates: 1
    2021-11-18 02:04:02.602 [http-nio-9999-exec-1] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction commit
    2021-11-18 02:04:02.602 [http-nio-9999-exec-1] DEBUG o.s.j.d.DataSourceTransactionManager - Committing JDBC transaction on Connection [HikariProxyConnection@1739907345 wrapping com.mysql.cj.jdbc.ConnectionImpl@28ddd184]
    2021-11-18 02:04:02.626 [http-nio-9999-exec-1] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1739907345 wrapping com.mysql.cj.jdbc.ConnectionImpl@28ddd184] after transaction
    2021-11-18 02:04:02.630 [http-nio-9999-exec-1] ERROR c.b.a.a.c.r.GlobalExceptionHandler - handleException
    java.lang.Exception: >>>>>>>>>> READONLY Transactional FORCE_THROW!!!!!
    	at service.ScheduleServiceImpl.insertTest4(ScheduleServiceImpl.java:66)
    	at service.ScheduleServiceImpl$$FastClassBySpringCGLIB$$635d091c.invoke(<generated>)
    	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    	at service.ScheduleServiceImpl$$EnhancerBySpringCGLIB$$d26e465e.insertTest4(<generated>)
    	at contorller.ScheduleController.test4(ScheduleController.java:37)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    	at java.lang.Thread.run(Thread.java:748)
    2021-11-18 02:04:02.669 [http-nio-9999-exec-1] WARN  o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [java.lang.Exception: >>>>>>>>>> READONLY Transactional FORCE_THROW!!!!!]

    결과

    1건 등록됨

    @Transactional 이 없는 경우

        public void selectTest1() {
    
            log.debug(">>>>>>>>>> NONE Transactional!!!!!");
            scheduleRepository.selectTest(1);
        }

    output log

    2021-11-18 02:20:38.745 [http-nio-9999-exec-2] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> NONE Transactional!!!!!
    2021-11-18 02:20:38.745 [http-nio-9999-exec-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
    2021-11-18 02:20:38.755 [http-nio-9999-exec-2] DEBUG c.b.a.a.m.s.r.S.selectTest - ==>  Preparing: select id, token from dummy_test where id = ?
    2021-11-18 02:20:38.755 [http-nio-9999-exec-2] DEBUG c.b.a.a.m.s.r.S.selectTest - ==> Parameters: 1(Integer)
    2021-11-18 02:20:38.762 [http-nio-9999-exec-2] DEBUG c.b.a.a.m.s.r.S.selectTest - <==      Total: 1

    결과

    1건 조회

    @Transactional(readonly = true) 인 경우

        @Transactional(readOnly = true)
        public void selectTest2() {
    
            log.debug(">>>>>>>>>> READONLY Transactional!!!!!");
            scheduleRepository.selectTest(1);
        }

    output log

    2021-11-18 02:21:19.842 [http-nio-9999-exec-4] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [service.ScheduleServiceImpl.selectTest2]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
    2021-11-18 02:21:19.849 [http-nio-9999-exec-4] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1712277285 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] for JDBC transaction
    2021-11-18 02:21:19.849 [http-nio-9999-exec-4] DEBUG o.s.jdbc.datasource.DataSourceUtils - Setting JDBC Connection [HikariProxyConnection@1712277285 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] read-only
    2021-11-18 02:21:19.849 [http-nio-9999-exec-4] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1712277285 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] to manual commit
    2021-11-18 02:21:19.857 [http-nio-9999-exec-4] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> READONLY Transactional!!!!!
    2021-11-18 02:21:19.857 [http-nio-9999-exec-4] DEBUG c.b.a.a.m.s.r.S.selectTest - ==>  Preparing: select id, token from dummy_test where id = ?
    2021-11-18 02:21:19.857 [http-nio-9999-exec-4] DEBUG c.b.a.a.m.s.r.S.selectTest - ==> Parameters: 1(Integer)
    2021-11-18 02:21:19.864 [http-nio-9999-exec-4] DEBUG c.b.a.a.m.s.r.S.selectTest - <==      Total: 1
    2021-11-18 02:21:19.864 [http-nio-9999-exec-4] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction commit
    2021-11-18 02:21:19.864 [http-nio-9999-exec-4] DEBUG o.s.j.d.DataSourceTransactionManager - Committing JDBC transaction on Connection [HikariProxyConnection@1712277285 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594]
    2021-11-18 02:21:19.878 [http-nio-9999-exec-4] DEBUG o.s.jdbc.datasource.DataSourceUtils - Resetting read-only flag of JDBC Connection [HikariProxyConnection@1712277285 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594]
    2021-11-18 02:21:19.878 [http-nio-9999-exec-4] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1712277285 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] after transaction

    결과

    1건 조회

    @Transactional(rollbackFor = Exception.class) 인 경우

        @Transactional(rollbackFor = Exception.class)
        public void selectTest3() {
    
            log.debug(">>>>>>>>>> OK Transactional!!!!!");
            scheduleRepository.selectTest(1);
        }

    output log

    2021-11-18 02:21:57.747 [http-nio-9999-exec-5] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [service.ScheduleServiceImpl.selectTest3]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.Exception
    2021-11-18 02:21:57.757 [http-nio-9999-exec-5] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1422949026 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] for JDBC transaction
    2021-11-18 02:21:57.757 [http-nio-9999-exec-5] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1422949026 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] to manual commit
    2021-11-18 02:21:57.763 [http-nio-9999-exec-5] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> OK Transactional!!!!!
    2021-11-18 02:21:57.763 [http-nio-9999-exec-5] DEBUG c.b.a.a.m.s.r.S.selectTest - ==>  Preparing: select id, token from dummy_test where id = ?
    2021-11-18 02:21:57.764 [http-nio-9999-exec-5] DEBUG c.b.a.a.m.s.r.S.selectTest - ==> Parameters: 1(Integer)
    2021-11-18 02:21:57.771 [http-nio-9999-exec-5] DEBUG c.b.a.a.m.s.r.S.selectTest - <==      Total: 1
    2021-11-18 02:21:57.772 [http-nio-9999-exec-5] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction commit
    2021-11-18 02:21:57.772 [http-nio-9999-exec-5] DEBUG o.s.j.d.DataSourceTransactionManager - Committing JDBC transaction on Connection [HikariProxyConnection@1422949026 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594]
    2021-11-18 02:21:57.785 [http-nio-9999-exec-5] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1422949026 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] after transaction

    결과

    1건 조회 됨

    @Transactional 만 있는 경우

        @Transactional
        public void selectTest4() {
    
            log.debug(">>>>>>>>>> Transactional!!!!!");
            scheduleRepository.selectTest(1);
        }

    output log

    2021-11-18 02:23:17.083 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [ScheduleServiceImpl.selectTest4]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
    2021-11-18 02:23:17.089 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1889925240 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] for JDBC transaction
    2021-11-18 02:23:17.089 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1889925240 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] to manual commit
    2021-11-18 02:23:17.095 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.s.ScheduleServiceImpl - >>>>>>>>>> Transaction!!!!!
    2021-11-18 02:23:17.095 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.r.S.selectTest - ==>  Preparing: select id, token from dummy_test where id = ?
    2021-11-18 02:23:17.096 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.r.S.selectTest - ==> Parameters: 1(Integer)
    2021-11-18 02:23:17.102 [http-nio-9999-exec-8] DEBUG c.b.a.a.m.s.r.S.selectTest - <==      Total: 1
    2021-11-18 02:23:17.103 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction commit
    2021-11-18 02:23:17.103 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Committing JDBC transaction on Connection [HikariProxyConnection@1889925240 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594]
    2021-11-18 02:23:17.115 [http-nio-9999-exec-8] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1889925240 wrapping com.mysql.cj.jdbc.ConnectionImpl@68c8b594] after transaction

    결과

    1건 조회됨

    댓글

Designed by Tistory.