Подтвердить что ты не робот

@Transactional в методе @PostConstruct

Я хочу читать текстовые данные (CSV файлы) в начале моего приложения и поместить его в свою базу данных.

Для этого я создал PopulationService с помощью метода инициализации (аннотация @PostConstruct).

Я также хочу, чтобы они исполнялись в одной транзакции, и поэтому я добавил @Transactional по тому же методу.

Однако, @Transactional, похоже, игнорируется: Сделка запускается/останавливается при моих методах DAO низкого уровня.

Нужно ли мне управлять транзакцией вручную?

4b9b3361

Ответ 1

это может быть полезно (http://forum.springsource.org/showthread.php?58337-No-transaction-in-transactional-service-called-from-PostConstruct):

В @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
            }
        });
   }
}

Ответ 2

Я думаю, что @PostConstruct только гарантирует завершение предварительной обработки/впрыска вашего текущего класса. Это не означает, что инициализация всего контекста приложения завершена.

Однако вы можете использовать систему событий spring для получения события, когда завершена инициализация контекста приложения:

public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
  public void onApplicationEvent(ContextRefreshedEvent event) {
    // do startup code ..
  }    
}

Подробнее см. в разделе документации Стандартные и пользовательские события.