【发布时间】:2023-02-25 09:47:08
【问题描述】:
我想马上用一个例子来展示。有这样一个存储库:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
String USER_CACHE = "users";
@Override
@CachePut(value = USER_CACHE, key = "#user.email", unless = "#result == null")
<S extends User> S save(S user);
@Override
@CacheEvict(value = USER_CACHE, key = "#user.email")
void delete(User user);
@Cacheable(value = USER_CACHE, key = "#email", unless = "#result == null")
User findByEmailIgnoreCase(String email);
}
并且有这样一种服务,可以保存用户的更改,并向邮件发送确认码:
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
private final UserRepository userRepository;
@Override
public User getUserByEmail(String email) {
return userRepository.findByEmailIgnoreCase(email);
}
@Override
@Transactional(isolation = Isolation.SERIALIZABLE)
public void createAppUser(RegistrationAppRequestDto registrationRequest) throws EmailSendingException {
User user = getUserByEmail(registrationRequest.getEmail());
user.setPassword(registrationRequest.getPassword());
user.setApp(true);
user.setActivated(false);
user.setActivationCode(UUID.randomUUID().toString());
user.setLastVisit(LocalDateTime.now());
if (Strings.isEmpty(user.getImg())) {
user.setImg(DEFAULT_IMG);
}
mailSender.sendWelcomeMessage(user);
userRepository.save(user);
}
}
问题是如果出现错误(例如,当向邮件发送消息时),对该用户所做的更改将保留在缓存中,并且这些更改不会进入数据库(这是正确的).有处理这种情况的做法吗?或者,我可以使用对象克隆,但我认为这是一种不好的做法。我将不胜感激任何帮助。
【问题讨论】:
-
如果您使用的是 JPA,请不要使用 Spring Cache,请为您的 JPA 提供程序(可能是 Hibernate)使用缓存集成,它将为您管理所有这些。如果您真的想使用 Spring Cache(在这种情况下我不推荐),这将是最佳实践并且会更好地集成,请使用将与事务保持一致的事务感知缓存管理器。
-
@M.Deinum 谢谢,我研究了休眠缓存的工作原理,它确实看起来像一个解决方案
标签: java spring caching spring-data-jpa spring-cache