[SPRING] @PostConstruct 메서드의 @Transactional
SPRING@PostConstruct 메서드의 @Transactional
내 응용 프로그램의 시작 부분에 텍스트 데이터 비품 (CSV 파일)을 읽고 데이터베이스에 저장하려고합니다.
이를 위해 초기화 메소드 (@PostConstruct annotation)로 PopulationService를 만들었습니다.
또한 이들을 단일 트랜잭션으로 실행해야하므로 동일한 메소드에서 @Transactional을 추가했습니다.
그러나 @Transactional은 무시되는 것처럼 보입니다. 트랜잭션은 낮은 수준의 DAO 메소드에서 시작 / 중지됩니다.
수동으로 트랜잭션을 관리해야합니까?
해결법
-
==============================
1.이 도움이 될 수 있습니다 (http://forum.springsource.org/showthread.php?58337-No-transaction-in-transactional-service-called-from-PostConstruct).
이 도움이 될 수 있습니다 (http://forum.springsource.org/showthread.php?58337-No-transaction-in-transactional-service-called-from-PostConstruct).
따라서 @PostConstruct에있는 어떤 것을 트랜잭션 내에서 실행하려면 다음과 같이해야합니다 :
@Service("something") public class Something { @Autowired @Qualifier("transactionManager") protected PlatformTransactionManager txManager; @PostConstruct private void init(){ TransactionTemplate tmpl = new TransactionTemplate(txManager); tmpl.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { //PUT YOUR CALL TO SERVICE HERE } }); } }
-
==============================
2.@PostConstruct는 현재 클래스의 전처리 / 삽입이 완료되었음을 보장합니다. 전체 응용 프로그램 컨텍스트의 초기화가 완료되었음을 의미하지는 않습니다.
@PostConstruct는 현재 클래스의 전처리 / 삽입이 완료되었음을 보장합니다. 전체 응용 프로그램 컨텍스트의 초기화가 완료되었음을 의미하지는 않습니다.
그러나 스프링 이벤트 시스템을 사용하여 응용 프로그램 컨텍스트의 초기화가 완료되면 이벤트를 수신 할 수 있습니다.
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> { public void onApplicationEvent(ContextRefreshedEvent event) { // do startup code .. } }
자세한 내용은 표준 및 사용자 정의 이벤트 설명서를 참조하십시오.
-
==============================
3.@ Platon Serbin의 대답이 저에게 효과적이지 않았습니다. 그래서 계속해서 내 삶을 살리는 다음과 같은 대답을 찾았습니다. :디
@ Platon Serbin의 대답이 저에게 효과적이지 않았습니다. 그래서 계속해서 내 삶을 살리는 다음과 같은 대답을 찾았습니다. :디
그 대답은 @PostConstruct의 No Session Hibernate이며, 나는 이것을 자유롭게 찍어서 쓸 수 있습니다 :
@Service("myService") @Transactional(readOnly = true) public class MyServiceImpl implements MyService { @Autowired private MyDao myDao; private CacheList cacheList; @Autowired public void MyServiceImpl(PlatformTransactionManager transactionManager) { this.cacheList = (CacheList) new TransactionTemplate(transactionManager).execute(new TransactionCallback(){ @Override public Object doInTransaction(TransactionStatus transactionStatus) { CacheList cacheList = new CacheList(); cacheList.reloadCache(MyServiceImpl.this.myDao.getAllFromServer()); return cacheList; } }); }
-
==============================
4.@PostConstruct 나 @NoTransaction 메소드에서 transactionOperations.execute ()를 사용하면
@PostConstruct 나 @NoTransaction 메소드에서 transactionOperations.execute ()를 사용하면
@Service public class ConfigurationService implements ApplicationContextAware { private static final Logger LOG = LoggerFactory.getLogger(ConfigurationService.class); private ConfigDAO dao; private TransactionOperations transactionOperations; @Autowired public void setTransactionOperations(TransactionOperations transactionOperations) { this.transactionOperations = transactionOperations; } @Autowired public void setConfigurationDAO(ConfigDAO dao) { this.dao = dao; } @PostConstruct public void postConstruct() { try { transactionOperations.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(final TransactionStatus status) { ResultSet<Config> configs = dao.queryAll(); } }); } catch (Exception ex) { LOG.trace(ex.getMessage(), ex); } } @NoTransaction public void saveConfiguration(final Configuration configuration, final boolean applicationSpecific) { String name = configuration.getName(); Configuration original = transactionOperations.execute((TransactionCallback<Configuration>) status -> getConfiguration(configuration.getName(), applicationSpecific, null)); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { } }
-
==============================
5.자기를 주입하고 그것을 통해 @Transactional 메서드 호출
자기를 주입하고 그것을 통해 @Transactional 메서드 호출
public class AccountService { @Autowired private AccountService self; @Transactional public void resetAllAccounts(){ //... } @PostConstruct private void init(){ self.resetAllAccounts(); } }
자체 주입을 지원하지 않는 이전 버전의 Spring에서는 BeanFactory를 주입하고 self를 beanFactory.getBean (AccountService.class)
from https://stackoverflow.com/questions/17346679/transactional-on-postconstruct-method by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 MVC 컨트롤러의 JSON 매개 변수 (0) | 2018.12.07 |
---|---|
[SPRING] 개체 목록을 thymeleaf에 바인딩하는 방법은 무엇입니까? (0) | 2018.12.07 |
[SPRING] Spring Web MVC - 개별 요청 매개 변수 유효성 검사 (0) | 2018.12.07 |
[SPRING] Spring @ 트랜잭션이 작동하지 않음 (0) | 2018.12.07 |
[SPRING] OPTIONS Http 메소드에 대한 스프링 보안 비활성화 (0) | 2018.12.07 |