@Transactional我想在我的應用程序的開始處讀取文本數據夾具(CSV文件)並將其放入我的數據庫中。@PostConstruct方法
爲此,我已經創建了一個PopulationService與一個初始化方法(@PostConstruct註釋)。
我也希望他們在一筆交易中執行,因此我在同一個方法中加入了@Transactional。
但是,@Transactional似乎被忽略: 事務在我的低級DAO方法開始/停止。
我需要手動管理交易嗎?
@Transactional我想在我的應用程序的開始處讀取文本數據夾具(CSV文件)並將其放入我的數據庫中。@PostConstruct方法
爲此,我已經創建了一個PopulationService與一個初始化方法(@PostConstruct註釋)。
我也希望他們在一筆交易中執行,因此我在同一個方法中加入了@Transactional。
但是,@Transactional似乎被忽略: 事務在我的低級DAO方法開始/停止。
我需要手動管理交易嗎?
在@PostConstruct(與afterPropertiesSet方法從InitializingBean接口僅)是沒有辦法,以確保所有的後處理已經完成,所以(實際上)不可能有交易。確保工作的唯一方法是使用TransactionTemplate。
所以,如果你想在你的@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
}
});
}
}
我認爲@PostConstruct
只確保您的當前課程的預處理/注入完成。這並不意味着整個應用程序上下文的初始化已完成。
但是你可以使用Spring事件系統來接收事件時,應用程序上下文的初始化完成:
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
public void onApplicationEvent(ContextRefreshedEvent event) {
// do startup code ..
}
}
查看文檔部分Standard and Custom Events更多的細節。
不過,如何讓我的「初始化」方法的事務? –
你有沒有試過從'onApplicationEvent()'方法調用你的transactional服務? – micha
你是對的,使用@Transactional這是最好的解決方案 –
@Platon Serbin稱的回答並沒有爲我工作。所以我一直在尋找,發現了下面的答案,挽救了我的生命。 :d
答案就在這裏No Session Hibernate in @PostConstruct,我冒昧地抄寫:
@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;
}
});
}
無論如何,我們可以攔截容器的「完成後處理」事件,以便我們知道交易現在可用嗎? – gerrytan
@gerrytan我相信這樣的事情可以通過使用Spring的[ApplicationListener](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/ApplicationListener.html)來實現。它允許監聽包括上下文生命週期事件在內的各種事件。 –
@gerrytan特別是[ContextRefreshedEvent](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html)應該滿足您的需求。每[文檔](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#context-functionality-events):_「...所有的豆都加載,後處理器bean被檢測和激活,單例被預先實例化,並且ApplicationContext對象已準備好使用...「_ –