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

Spring忽略@事务性注释

堵宏毅
2023-03-14

在我们的一个项目中,我们遇到了一个问题,Spring忽略了事务注释,然后失败了,出现了以下错误。

启动ApplicationContext时出错。要显示条件报告,请在启用“调试”的情况下重新运行应用程序。2018-09-13 15:05:18406错误[主]组织。springframework。靴子SpringApplication应用程序运行失败组织。springframework。道。InvalidDataAccessApiUsageException:当前线程没有具有实际事务的EntityManager-无法可靠地处理“remove”调用;嵌套的异常是javax。坚持不懈TransactionRequiredException:当前线程没有具有实际事务的EntityManager-无法可靠地处理com上的“remove”调用。我的服务CacheAService。deleteShortTermCache(CacheAService.java:70)~[类/:na]

我发现了类似的问题,但没有一个解决方案适用于这个案例。

  • @EnableTransactionManagement存在
  • 事务类实现接口
  • 事务方法是公共的
  • 事务方法未在内部调用

当我用事务性注释CacheService时,一切都会重新运行。但我试图理解为什么Spring会忽略CacheAService上的事务性。

我尝试记录Spring的事务拦截器,但没有提到CacheA。这是唯一记录的相关内容。

2018-09-13 15:05:18242跟踪[主]组织。springframework。交易拦截器。TransactionInterceptor不需要为[org.springframework.data.jpa.repository.support.SimpleParepository.deleteByValidity]创建事务:此方法不是事务性的。

下面是简化的代码。Spring的上下文刷新事件(ContextRefreshedEvent)在应用程序启动期间调用代码。

@Service
public class CacheService implements Cache {

    @Autowired
    private CacheA cacheAService;
    @Autowired
    private CacheB cacheBService;

    @Override
    public void clearCache() {
        cacheAService.deleteShortTermCache();
        cacheBService.deleteAll();
    }
}

public interface CacheA {
    void deleteShortTermCache();
}

@Service
@Transactional(readOnly = true)
public class CacheAService implements CacheA {

    @Autowired
    private CacheARepository cacheARepository;

    @Override
    @Transactional
    public void deleteShortTermCache() {
        cacheARepository.deleteByValidity(CacheValidity.SHORT_TERM);
    }
}

public interface CacheB {
    void deleteAll();
}

@Service
@Transactional(readOnly = true)
public class CacheBService implements CacheB {

    @Autowired
    private CacheBRepository cacheBRepository;

    @Override
    @Transactional
    public void deleteAll {
        cacheBRepository.deleteAll();
    }
}

public enum CacheValidity {
    SHORT_TERM,
    LONG_TERM
}

@Repository
public interface CacheARepository extends JpaRepository<CacheItem, Integer> {
    void deleteByValidity(CacheValidity validity);
}

public enum CacheItemKey {
    AVAILABLE,
    FUTURE,
    AVAILABLE_UTM,
    FUTURE_UTM,
    REGION
}

@Entity
@Table(name = "cache_item")
public class CacheItem {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cache_item_id_seq")
    @SequenceGenerator(name = "cache_item_id_seq", sequenceName = "cache_item_id_seq", allocationSize = 1)
    private Integer id;

    @Column(nullable = false, unique = true)
    @Enumerated(EnumType.STRING)
    private CacheItemKey key;

    @Column(nullable = false)
    private String value;

    @Column(name = "date_modified", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateModified;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private CacheValidity validity;

    public Integer getId() {
        return id;
    }

    public void setId(final Integer id) {
        this.id = id;
    }

    public CacheItemKey getKey() {
        return key;
    }

    public void setKey(final CacheItemKey key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(final String value) {
        this.value = value;
    }

    public Date getDateModified() {
        return dateModified;
    }

    public void setDateModified(final Date dateModified) {
        this.dateModified = dateModified;
    }

    public CacheValidity getValidity() {
        return validity;
    }

    public void setValidity(final CacheValidity validity) {
        this.validity = validity;
    }

}

编辑:经过一番挖掘,我在日志中发现了这个。

2018-09-14 06:24:11174信息[localhost-startStop-1]组织。springframework。上下文支持[com.my.service.cacheAService]类型的PostProcessorRegistrationLegate$BeanPostProcessorChecker Bean“cacheAService”不符合由所有BeanPostProcessor处理的条件(例如:不符合自动代理的条件)

共有2个答案

孟晨朗
2023-03-14

尝试只使用一个Transactional注释(在类或方法中)。可能是@Transactional(只读=true)的问题,因为您的事务不是只读的,我不确定Spring更喜欢什么Transactional注释。尝试使用:

@Service
public class CacheAService implements CacheA {

    @Autowired
    private CacheARepository cacheARepository;

    @Override
    @Transactional
    public void deleteShortTermCache() {
        cacheARepository.deleteByValidity(CacheValidity.SHORT_TERM);
    }
}

@Service
@Transactional
public class CacheAService implements CacheA {

    @Autowired
    private CacheARepository cacheARepository;

    @Override
    public void deleteShortTermCache() {
        cacheARepository.deleteByValidity(CacheValidity.SHORT_TERM);
    }
} 
刘海
2023-03-14

我们发现这个问题是由Spring Boot的自动配置引起的。由于自动配置已经设置了事务管理,我们的自定义配置@EnableTransactionManagement破坏了事务顾问的实例化。从我们的配置中删除@EnableTransactionManagement可以解决这个问题。

 类似资料:
  • 有什么想法为什么@primary在这里没有被考虑在内吗?

  • 问题内容: 我的@Transactionnal注释似乎被忽略了。我对Spring容器的初始化没有任何错误。看来我的方法尚未被Spring TX框架代理。在执行服务的方法期间,JDBCTemplate会引发预期的RuntimeException。问题在于JDBC连接没有回滚,并且更改保持不变。stacktrace没有显示应该包装我的服务方法的代理的任何迹象。 编辑:添加了控制器的代码 编辑2:添加了

  • 我正在阅读使用Spring框架的事务管理。在第一个组合中,我使用Spring Hibernate和Hibernate的API来控制事务(Hibernate API)。接下来,我想使用注释进行测试,它确实起了作用。 我感到困惑的是: > JPA、JTA、Hibernate是否有自己的事务管理方式。举个例子,考虑如果我使用Spring Hibernate,在那种情况下,你会使用“JPA”事务吗? 就像

  • 我正在迁移一个活动的Spring Web应用到Spring Boot(1.4.2)。 这些bean是在XML中定义的,因为它正在加载@重要资源。 我正在启动的4个bean是同一个对象BasicDataSource的实例。 为了告诉Spring要加载哪个,我为每个都设置了一个ID,并使用@Qualifer将正确的bean绑定到变量。 但Spring似乎忽略了我的@Qualifier,并抛出“没有可用

  • 我有一个具有依赖项的Spring Boot应用程序。我的实体类有一个带有列名的列注释。例如: 由此生成的SQL将创建为列名。在寻找解决方案之后,我发现解决了这个问题(列名取自列注释)。 但是,我的问题是为什么没有将naming_strategy设置为,JPA忽略列注释?也许冬眠方言与此有关?我正在连接到MS SQL 2014 Express,我的日志包含:

  • 试图收集和理解@事务性注释的要点并越过了一点。因此,在使用事务性注释时,我们需要记住的主要事情是: 事务注释只能应用于公共方法[根据Spring@Transactional属性对私有方法起作用吗? 事务性注释应该应用于具体的类,而不是接口[根据我应该将@transactional annotation放在接口定义还是实现类的位置? 事务注释应应用于服务级别[根据Spring@Transaction