我使用Spring缓存抽象使用Ehache作为缓存提供程序。我试图将缓存操作附加到Spring JPA事务,但无法这样做。
即使事务失败/回滚缓存放发生。
配置,
@Bean
public EhCacheManagerFactoryBean cacheManagerUsingSpringApi() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
// provide xml file for ehcache configuration/
ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("spring-cache-abs-ehcache.xml"));
return ehCacheManagerFactoryBean;
}
@Bean
public org.springframework.cache.CacheManager ehCacheCacheManager() {
final EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(cacheManagerUsingSpringApi().getObject());
ehCacheCacheManager.setTransactionAware(true); // Setting transaction aware
return ehCacheCacheManager;
}
springcache-abs-ehcache。xml,
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<cache name="EmployeeCache"
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
雇员安置处,
public interface EmployeeRepository extends JpaRepository<Employee, Long>, CustomEmployeeRepository {
}
事务方法,
@Repository
public class EmployeeRepositoryImpl implements CustomEmployeeRepository {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private CacheManager cacheManager;
// THIS METHOD SHOULD NOT PUT INTO CACHE WITH NEW NAME
@Override
@Transactional
@Cacheable(cacheNames = "EmployeeCache", key = "#a0.id")
public Employee customUpdate(Employee employee) {
employee.setFirstName(UUID.randomUUID().toString());
entityManager.merge(employee);
// rolling back transaction
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return employee;
}
}
测试用例(调用者),
@Test
public void testCustomUpdate() {
// GIVEN
Employee employee = new Employee();
employee.setFirstName(UUID.randomUUID().toString());
employee.setLastName(UUID.randomUUID().toString());
final Employee savedEmployee = employeeRepository.save(employee);
// WHEN
final Employee updatedEmployee = employeeRepository.customUpdate(savedEmployee);
// THEN
final Cache employeeCache = cacheManager.getCache("EmployeeCache");
final Cache.ValueWrapper object = employeeCache.get(updatedEmployee.getId());
assertNull(object);
}
测试应该成功,也就是说,如果事务在该方法中回滚,Spring不应该将数据放入方法雇员Repository.custom更新
中的缓存中。但是,即使事务失败,Spring也会将数据放入缓存。注意:奇怪的部分是,如果条目已经存在于缓存中,那么@CachePUT不会在事务失败时更新缓存中的条目。
所以,如果我注释雇员Repository.save
与@CachePUT(cacheNames="雇员缓存",key="#result.id")
然后缓存不更新更新调用。
这里少了什么?
参考:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-订购
下面的声明将首先执行事务性建议,然后执行可缓存建议。
<tx:annotation-driven order="0"/>
<cache:annotation-driven cache-manager="ehCacheManager" order="1"/>
如果从另一个用@Transactional注释的方法调用@Cacheable注释的方法,您将看到代码正在工作。同一方法上的@Cacheable和@Transaction这两个注释都不会对您的原因有所帮助,除非您实现了建议排序。请看下面一个粗略的逻辑实现。
@Override
@Transactional
public Employee customUpdate(Employee employee) {
Employee mergedEmployee = updateHelper(employee);
// rolling back transaction
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return mergedEmployee;
}
@Cacheable(cacheNames = "EmployeeCache", key = "#a0.id")
public Employee updateHelper(Employee employee)) {
employee.setFirstName(UUID.randomUUID().toString());
//On a merge(...) call on the entityManager, the returned item is the managed
//instance
return entityManager.merge(employee);
}
嗨,我正在尝试开发带有事务的spring和hibernate应用程序,我正在使用Spring4。x和hibernate 4。下面是我的代码片段 应用程序上下文。xml servlet上下文。xml 坚持。xml finnaly meservice看起来像这样 和 这里会发生运行时异常,但db记录没有回滚。
我正在探索Ignite事务性缓存。我已经有了一段代码,它对JDBC使用Spring事务管理。我想使用Spring缓存抽象在代码中集成ignite事务性缓存。 我遇到了SpringTransactionManager(由Ignite提供),但我无法找到正确的使用方法。本质上,我想做一些类似的事情: 当事务提交时,数据库和缓存应该一起提交。为此,Ignite文档提到了使用SpringTransacti
我是一个新的Spring和学习的事务概念。无法使@Transactional工作。 用例: 当getEmployee()抛出RuntimeException时,员工和员工详细信息的数据插入应该回滚。但回滚没有发生。我使用的是Oracle数据库11g和spring 4.3.1版本。下面是正在运行的独立java代码。
我使用的是grails 1.3.7,代码如下: Grails服务: 我的例外: } 当代码抛出MyException时,我发现以下错误:事务回滚,因为它已被标记为仅回滚 注:如果我更改static transactional=true,则不会发生错误。 知道吗?
我将Spring 3.2.4与JavaFX结合使用,并希望实现一种方法,其中操作将在事务中执行。我在控制器中的代码如下所示: 以及我的应用程序上下文: 尝试运行时,我收到以下错误消息: 该方法存在。删除注释,或者将方法从public更改为private,或者从配置中删除bean,程序就会运行,但事务注释根本不起作用。删除代理目标会导致另一个错误。
我想将主数据缓存到Redis。 所以,我写了这些代码。 和 和ymlfile 但是,缓存不工作... 无论何时调用printTest方法,都将执行“getTest”方法。Redis没有数据。。。我的代码中有什么问题? SpringBoot版本是1.4.0 依赖关系是