在单个事务中保存到 Reactive Redis 和 Postgres

问题描述 投票:0回答:1

我希望在事务中执行对 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)
        );
    }
postgresql redis transactions spring-webflux reactive
1个回答
0
投票

在底层使用 JPA 时实现这一点并不简单,因为您需要对事务管理进行精细控制,同时您使用

@Transactional
自动管理事务。

我建议使用普通的

JdbcTemplate
(或新的
JdbcClient
)和
RedisTemplate

您想在单个线程中执行以下操作。

  1. 在 PostgreSQL 中启动事务。
  2. 对 PostgreSQL 执行 SQL 查询,不要提交任何内容!
  3. 现在判断:PostgreSQL保存成功了吗?
    • 如果是,则执行Redis保存操作,并根据其结果提交/回滚PostgreSQL事务。
    • 如果没有,则回滚 PostgreSQL 事务。

不知道你是在PostgreSQL数据库中插入还是更新一条记录。如果出现

UPDATE
,您可能希望确保没有其他节点更新与另一个节点相同的行,因此我建议使用
SELECT FOR UPDATE
锁定记录。

© www.soinside.com 2019 - 2024. All rights reserved.