在 Spring Boot Transaction 中以只读方式执行 RxJava observable?
Posted
技术标签:
【中文标题】在 Spring Boot Transaction 中以只读方式执行 RxJava observable?【英文标题】:Execute RxJava observable as readOnly within Spring boot Transaction? 【发布时间】:2017-03-27 23:10:51 【问题描述】:在我的 Spring Boot 应用程序中,我像这样异步调用了几个数据库:
public List<Results> doWork()
List<Observable<Results>> observables = Lists.newArrayList();
observables.add(
Observable.fromCallable(() -> dbQueryMethod(param1)).subscribeOn(Schedulers.io()));
observables.add(
Observable.fromCallable(() -> dbQueryMethod(param2)).subscribeOn(Schedulers.io()));
return Observable.merge(observables)
.toList()
.toBlocking()
.single();
@Transactional(readOnly=true)
public List<Results> myServiceMethod()
doWork();
基本上问题是,尽管将我的服务层方法标记为事务和只读设置为 true,它实际上并没有将 ThreadLocal 状态传递给由 RxJava 生成的新线程,导致连接转到我的主数据库实例而不是只读副本。
我们目前正在使用已配置的ContextHandlers
和App.java
中的ContextAwareSchedulerHook
,但是我需要做什么才能使 RxJava 创建的新线程将继承所需的任何 ThreadLocal 状态,以便在定义的事务中管理它们?
【问题讨论】:
您可以使用 SchedulerHook 将本地线程复制到另一个线程,请参阅blog.mabn.pl/2014/11/rxjava-logback-and-mdc-threadlocal.html(适用于 RxJava 1) @dwursteisen 但是有什么可以说明如何专门针对春季 JDBC 状态执行此操作的吗? 【参考方案1】:用@Transactional(readOnly=true)
标记您的dbQueryMethod
,并确保您通过Spring 自动装配代理(而不是直接来自同一个类)调用它。然后io
线程将启动新事务,该事务是只读的。
【讨论】:
以上是关于在 Spring Boot Transaction 中以只读方式执行 RxJava observable?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 2 / Kotlin / JDK9 - 引起:java.lang.ClassNotFoundException:javax.transaction.SystemExceptio