我希望在事务中执行对 Postgres 和 Redis 的保存,这意味着如果其中一个保存遇到错误,另一个保存应该回滚。如何才能实现这一目标?我希望 saveLocationToDbAndRedis() 方法发生在单个事务中。
private final ReactiveRedisOperations<String, RedisLocation> locationOps;
....
@Transactional
Mono<Location> saveLocationToPostgres(Location location) {
return ioMono(() -> locationRepository.save(location));
}
@Transactional
public Mono<Location> saveLocationToDbAndRedis(Location location) {
return saveLocationToPostgres(location)
.zipWith(redisLocationHashOperations.saveAndUpdateLocationInRedis(location))
.flatMap(locationBooleanTuple -> Mono.just(locationBooleanTuple.getT1()));
}
public Mono<Boolean> saveAndUpdateLocationInRedis(Location location) {
return locationOps.opsForHash().put(
REDIS_HASH_LOCATION_KEY,
location.getId(),
toRedisLocation(location)
);
}
在底层使用 JPA 时实现这一点并不简单,因为您需要对事务管理进行精细控制,同时您使用
@Transactional
自动管理事务。
我建议使用普通的
JdbcTemplate
(或新的 JdbcClient
)和 RedisTemplate
。
您想在单个线程中执行以下操作。
不知道你是在PostgreSQL数据库中插入还是更新一条记录。如果出现
UPDATE
,您可能希望确保没有其他节点更新与另一个节点相同的行,因此我建议使用 SELECT FOR UPDATE
锁定记录。