如何确保RXJava Observable指令在线程范围内执行?

时间:2016-01-11 16:21:53

标签: java rx-java

我目前正在将RXJava与数据库事务结合使用。这些数据库事务不是线程安全的,因此必须在单个线程的范围内执行所有操作。

一种解决方案是将Observable转换为阻塞observable并调用单个或最后一个方法。这样,在同一线程内执行所有可观察指令(如果没有另外指定)。一旦处理完所有指令,try-with-resources语句将调用close。

try (Trx tx = db.trx()) { obs.toBlocking().single(); }

或者,可以使用调度程序:

  1. 将可观察指令绑定到某个线程
  2. 在调用onCompleted时关闭事务。
  3. 是否可以使用任何其他替代方法来确保可观察指令在单个线程的范围内执行?

1 个答案:

答案 0 :(得分:2)

鉴于您的示例代码,我假设您正在以可观察的副作用(例如doOnNext)访问数据库,而不是在订阅调用中,不确定这是否有意,但您最好依赖于副作用(用于写入)的订阅代码或您要合并的可观察源(用于读取)。

请注意toBlocking().single()并不保证您的可观察副作用会在当前线程中发生,而只会保证它们全部终止。

更简单的方法(写入)可能是这样做的:

obs.toList().subscribe(list -> 
    try (Trx tx = db.trx()) {
        // do DB stuff foreach item in list
    })

(如果您的观察结果未终止,则使用buffer代替toList会很好)

如果您处理JDBC,您还可以查看rxjava-jdbc。实际上,即使你不这样做,库语法也可以提供有关如何将数据库事务与Rx粘合的提示。