当前位置: 首页 > 知识库问答 >
问题:

@@PostConstruct方法上的事务

仲高超
2023-03-14

我想在我的应用程序开始时读取文本数据夹具(CSV文件),并将其放入数据库。

为此,我创建了一个带有初始化方法的PopulationService(@PostConstruct注释)。

我还希望它们在单个事务中执行,因此我在同一个方法上添加了@Transactional。

然而,@Transactional似乎被忽略了:事务在我的低级DAO方法中启动/停止。

那么我需要手动管理交易吗?

共有3个答案

华宪
2023-03-14

作为更新,从Spring 4.2开始,@EventListener注释允许更干净的实现:

@Service
public class InitService {

    @Autowired
    MyDAO myDAO;

    @EventListener(ContextRefreshedEvent.class)
        public void onApplicationEvent(ContextRefreshedEvent event) {
        event.getApplicationContext().getBean(InitService.class).initialize();
    }

    @Transactional
    public void initialize() {
        // use the DAO
    }

}

晏望
2023-03-14

我认为@PostConstruct只能确保当前类的预处理/注入完成。这并不意味着整个应用程序上下文的初始化已经完成。

但是,当应用程序上下文初始化完成时,您可以使用spring事件系统接收事件:

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

有关更多详细信息,请参阅留档部分标准和自定义事件。

傅泉
2023-03-14

引自legacy(非公开)Spring论坛:

在@PostConstruct中(与来自InitializingBean接口的AfterPropertieSet一样),无法确保所有的后处理都已经完成,因此(实际上)不可能有任何事务。确保该功能正常工作的唯一方法是使用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
            }
        });
   }
}
 类似资料:
  • 问题内容: 我想在应用程序开始时阅读文本数据装置(CSV文件),并将其放入数据库中。 为此,我创建了带有初始化方法(@PostConstruct批注)的PopulationService。 我也希望它们在单个事务中执行,因此我在同一方法上添加了@Transactional。 然而,@Transactional似乎被忽略:该交易启动/停止我的低水平DAO方法。 那我需要手动管理交易吗? 问题答案:

  • 我正在试验JavaEE7、CDI、JPA和JSF。 当webapp启动时,我想在我的cdibean(用@PostConstruct标记)中运行一个初始化方法,该方法对数据库进行一些操作(插入一些行等)。为此,我需要一笔交易,但这并不像我预期的那么容易。 我曾尝试将@Transactional注释添加到我的方法中,但显然它只适用于EJB。实际上,我尝试将bean转换为EJB而不是cdibean,但仍

  • 我将HiberNate与Panache一起使用,并且需要在应用程序启动时添加用户。为此,我使用注释我的bean,然后我有一个带有注释的方法。 目前,我正在使用以下代码: 据我发现,当调用此方法时,不能保证所有内容都已经设置好,我想这就是为什么它有时会失败并出现错误的原因。我已经检查过这个问题,但由于它是针对 Spring 的,因此该方法不起作用,我没有找到任何类似的东西 Quarkus。 我是否缺

  • 问题内容: SampleBean: 和配置文件是这样的: 而且我没有在bean标记上设置default-init-method属性。 任何机构都可以说出为什么@PostConstruct方法没有被调用的原因。 问题答案: 你需要(或)启用处理功能。

  • 我在将E3 RCP应用程序迁移到E4时遇到了问题。我有三个部分。2.样品含量为Lars Vogel(http://www.vogella.com/tutorials/EclipseRCP/article.html#plugin_creatinge4“使用SWT电源小部件”)进行测试,并将其与我的部件进行比较。 长话短说(er):应该创建视图内容的方法(标记为@PostConstruct)不会被调用

  • 问题内容: 构造bean之后,我想使用EntityManager从数据库中检索数据。在构造函数中是不可能的,因为EntityManager是在调用构造函数之后注入的。所以我试图用@PostConstruct注释的方法来做。根据API,在完成所有注入后将调用PostConstruct方法。执行查询是可行的,但是它总是返回一个空列表。如果我在其他方法中使用相同的查询,它将返回正确的结果。有人知道,为什