-
@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건 조회됨
'Spring' 카테고리의 다른 글
프로젝트 회고 - 수업 스케줄 일괄 변경 배치 처리 (0) 2024.04.08 프로젝트 회고 - 스케줄 자동 공개 성능 최적화 (1) 2024.04.04 Spring Version에 맞는 h2Database 설치 (0) 2023.04.16 web.xml 에 선언된 context-param, init-param 테스트 (0) 2021.06.30 @ConfigurationProperties 사용해보기 (0) 2021.05.18 - insert(insert 만 테스트 했지만, commit 관련해서는 update, delete 도 동일합니다.)