3

对事务流的支持似乎是最近才实现的,但由于它的新颖性,代码示例并不多。

有人可以展示一个事务流的示例,它执行一系列数据库插入,然后在成功时返回一些值,但在插入之间有一个中游检查点,用于测试某些条件并可能回滚事务并根据检查点返回不同的值结果?

4

1 回答 1

6

反应式事务遵循与命令式事务相同的模式:

  1. 在运行任何用户空间命令之前启动事务
  2. 运行用户空间命令
  3. 提交(或回滚)

这里需要注意的几个方面: 连接总是与反应序列的具体化相关联。我们从Thread绑定到命令式编程中的执行的绑定连接中所知道的内容转化为反应式编程中的物化。

因此,每个(并发)执行都会分配一个连接。

Spring Data R2DBC 不支持保存点。查看以下代码示例,该示例说明了提交或回滚的决定:

DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);

TransactionalOperator transactionalOperator = TransactionalOperator
        .create(new R2dbcTransactionManager(connectionFactory));

transactionalOperator.execute(tx -> {

    Mono<Void> insert = databaseClient.execute("INSERT INTO legoset VALUES(…)")
            .then();

    Mono<Long> select = databaseClient.execute("SELECT COUNT(*) FROM legoset")
            .as(Long.class)
            .fetch()
            .first();

    return insert.then(select.handle((count, sink) -> {

        if(count > 10) {
            tx.setRollbackOnly();
        }

    }));
}).as(StepVerifier::create).verifyComplete();

这里值得注意的方面是:

  1. 我们使用TransactionalOperator而不是@Transactional.
  2. .handle()调用setRollbackOnly()中用于回滚事务的代码。

使用@Transactional,您通常会使用异常来表示回滚条件。

于 2019-06-24T17:57:43.677 回答