【问题标题】:Spring @Transactional annotation is not workingSpring @Transactional 注释不起作用
【发布时间】:2015-08-22 13:24:26
【问题描述】:

我正在尝试在以下方法中运行 entityManager.merge(myEntity),但似乎忽略了 @Transactional 注释。 Hibernate 配置似乎很好,因为我可以成功地从数据库中获取数据,但无法写入数据库。我正在使用 Spring 3.2.3 版。为什么写入数据库操作不起作用?

我的方法不起作用

package  com.reflections.importer.bls;
...

@Service
class BlsGovImporter {

...

    @Transactional
    private void importSeries(String externalId) {
        // This works. The dao is using EntityManager too
        Series series = seriesDao.findByExternalId(externalId);

        series.getValues().addAll(fetchNewValues());

        // This does not work and no exception is thrown 
        entityManager.merge(series);
    }

【问题讨论】:

  • 您的 BlsGovImporter 类位于哪个包中?在“com.reflections”中?
  • 它位于 com.reflections.importer.bls 包中

标签: java spring hibernate spring-mvc spring-transactions


【解决方案1】:

因为它用于私有方法。 Spring Docs:

方法可见性和@Transactional

当使用代理时,你应该应用@Transactional注解 仅适用于具有公共可见性的方法。如果您确实注释受保护, 带有 @Transactional 注释的私有或包可见方法, 没有引发错误,但带注释的方法没有表现出 配置的事务设置。考虑使用 AspectJ(参见 下面)如果您需要注释非公共方法。

当它是私有的时,它显然是从同一个类中调用的。但是 Spring 调用需要通过代理才能使其正常工作。因此需要从另一个 bean 调用该方法。

其他选项是使用@Transactional 注释类。

【讨论】:

  • 即使是public,如果从同一个类的另一个方法调用,也不会使用代理,@Transactional也会被忽略
  • 公开该方法首先并没有解决我的问题。但是另外将 @Transactional 注释添加到另一个方法中,而不是从同一个类中调用,最终解决了我的问题。现在我正在考虑使用aspectj
  • @SergeBallesta,你是对的,我更新了我的答案。
  • 有几个选项可以使用同一类中的@Transactional: 1. 将 Spring 配置为使用 AspectJ 而不是 Spring AOP 2. 自自动装配 bean 并通过注入的引用调用方法 See here for more info
【解决方案2】:

luboskrnac 实际上确实为我回答了这个问题,但只是将此添加到可能对是否使用代理感到困惑的 Spring 新手。

请参考这个页面解释即使你在同一个类中调用@Transactional方法,由于你在没有同一个类的情况下调用它,它不会被代理调用。

https://www.logicbig.com/tutorials/spring-framework/spring-data-access-with-jdbc/correct-use-of-declarative-transaction.html

【讨论】:

    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    相关资源
    最近更新 更多