在我们的一个项目中,我们遇到了一个问题,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处理的条件(例如:不符合自动代理的条件)
尝试只使用一个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);
}
}
我们发现这个问题是由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