[컴] spring에서 @Transactional 이 동작하는지 확인하는 방법

spring transaction / transactional / 스프링 / spring boot

spring에서 @Transactional 이 동작하는지 확인하는 방법

@Transactional 이 제대로 동작하려면

spring 에서 @Transactional 를 사용하려면, public method 에 annotation 을 달아야 한다. 정확히는 이 @Transactional이 붙어있는 method 를 현재 @Bean 말고, 다른 Bean 에서 호출해줘야 한다.

  • [Using @Transactional :: Spring Framework](https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html)
  • [java - Spring @Transactional annotation is not working - Stack Overflow](https://stackoverflow.com/questions/32156652/spring-transactional-annotation-is-not-working)

@Transactional 동작하는지 확인하는 방법

  • TransactionAspectSupport.currentTransactionStatus
    import org.springframework.transaction.interceptor.TransactionAspectSupport;
    ...
    status = TransactionAspectSupport.currentTransactionStatus();
    • Transaction 이 동작하지 않았다면, NoTransactionException 을 던지게 된다.
  • call stack
    • TransactionInterceptor.invoke : call stack 에 TransactionInterceptor.invoke가 보인다.
    • call stack

@Transactional method 를 다른 Bean 에서 호출해야 하는 이유

다른 Bean 에서 호출하지 않고, 현재 @Bean 내의 method 에서 @Transactional method 를 호출하는 것으로는 bean 을 생성하지 않는다. 그러니까 spring 이 처음 run 할 때 @Transactional에 대한 proxy class 를 만드는데, 그 작업을 하지 않는 것 같다.

cglib 를 호출할 때의 call stack:

- SpringNamingPolicy.getClassName(String,String,Object,Predicate) (\spring-core-6.0.7.jar\org.springframework.cglib.core\SpringNamingPolicy.class:41)
- AbstractClassGenerator.generateClassName(Predicate) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:169)
- AbstractClassGenerator.generate(AbstractClassGenerator$ClassLoaderData) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:339)
- Enhancer.generate(AbstractClassGenerator$ClassLoaderData) (\spring-core-6.0.7.jar\org.springframework.cglib.proxy\Enhancer.class:575)
- AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:103)
- 0x0000000800f7bf70.apply(Object) (Unknown Source:-1)
- LoadingCache.lambda$createEntry$1(Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core.internal\LoadingCache.class:52)
- 0x0000000800f7c5c0.call() (Unknown Source:-1)
- FutureTask.run() (\java.base\java.util.concurrent\FutureTask.class:264)
- LoadingCache.createEntry(Object,Object,Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core.internal\LoadingCache.class:57)
- LoadingCache.get(Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core.internal\LoadingCache.class:34)
- AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator,boolean) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:126)
- AbstractClassGenerator.create(Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:313)
- Enhancer.createHelper() (\spring-core-6.0.7.jar\org.springframework.cglib.proxy\Enhancer.class:562)
- Enhancer.createClass() (\spring-core-6.0.7.jar\org.springframework.cglib.proxy\Enhancer.class:407)
- ConfigurationClassEnhancer.createClass(Enhancer) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassEnhancer.class:138)
- ConfigurationClassEnhancer.enhance(Class,ClassLoader) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassEnhancer.class:109)
- ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassPostProcessor.class:514)
- ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassPostProcessor.class:304)
- PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Collection,ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.support\PostProcessorRegistrationDelegate.class:358)
- PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory,List) (\spring-context-6.0.7.jar\org.springframework.context.support\PostProcessorRegistrationDelegate.class:150)
- AbstractApplicationContext.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.support\AbstractApplicationContext.class:747)
- AbstractApplicationContext.refresh() (\spring-context-6.0.7.jar\org.springframework.context.support\AbstractApplicationContext.class:565)
- ServletWebServerApplicationContext.refresh() (\spring-boot-3.0.5.jar\org.springframework.boot.web.servlet.context\ServletWebServerApplicationContext.class:146)
- SpringApplication.refresh(ConfigurableApplicationContext) (\spring-boot-3.0.5.jar\org.springframework.boot\SpringApplication.class:732)
- SpringApplication.refreshContext(ConfigurableApplicationContext) (\spring-boot-3.0.5.jar\org.springframework.boot\SpringApplication.class:434)
- SpringApplication.run(String[]) (\spring-boot-3.0.5.jar\org.springframework.boot\SpringApplication.class:310)
- FishApplication.main(String[]) (d:\a\prog\foodpang\purchase\fish\fish\src\main\java\co\foodpang\fish\FishApplication.java:24)
- NativeMethodAccessorImpl.invoke0(Method,Object,Object[])[native method] (\java.base\jdk.internal.reflect\NativeMethodAccessorImpl.class:-1)
- NativeMethodAccessorImpl.invoke(Object,Object[]) (\java.base\jdk.internal.reflect\NativeMethodAccessorImpl.class:77)
- DelegatingMethodAccessorImpl.invoke(Object,Object[]) (\java.base\jdk.internal.reflect\DelegatingMethodAccessorImpl.class:43)
- Method.invoke(Object,Object[]) (\java.base\java.lang.reflect\Method.class:568)
- RestartLauncher.run() (\spring-boot-devtools-3.0.5.jar\org.springframework.boot.devtools.restart\RestartLauncher.class:49)

댓글 없음:

댓글 쓰기