gpt4 book ai didi

java - Spring 忽略@Transactional 注解

转载 作者:行者123 更新时间:2023-11-30 07:44:44 28 4
gpt4 key购买 nike

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

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2018-09-13 15:05:18,406 ERROR [main] org.springframework.boot.SpringApplication Application run failed org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call at com.my.service.CacheAService.deleteShortTermCache(CacheAService.java:70) ~[classes/:na]

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

  • @EnableTransactionManagement 存在
  • 事务类实现接口(interface)
  • 交易方法是公开的
  • 事务方法不在内部调用

当我用@Transactional 注释CacheService 时,一切又恢复正常了。但我试图理解为什么 Spring 会忽略 CacheAService 上的 @Transactional

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

2018-09-13 15:05:18,242 TRACE [main] org.springframework.transaction.interceptor.TransactionInterceptor Don't need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.deleteByValidity]: This method isn't transactional.

这是简化的代码。 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:11,174 INFO [localhost-startStop-1] org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker Bean 'cacheAService' of type [com.my.service.CacheAService] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

最佳答案

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

关于java - Spring 忽略@Transactional 注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52315188/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com