thắc mắc [Quarkus] Transaction trong một thread khác

Kim Ah Joong

Senior Member
Mình đang migrate app spring qua quarkus mà gặp một vấn đề liên quan đến transaction khi thực hiện query trong một thread khác như này

Mình có 1 api start job. Khi gửi start job, api cứ trả về true thôi còn job sẽ được chạy backgroud vì nó mất nhiều thời gian (mình đang sử dụng rxjava để chạy job). Trong quá trình chạy job thì sẽ sử dụng PanacheEntity để update trạng thái của job. Vì nó thực hiện transaction ở một thread khác nên nó bị lỗi như bên dưới :beat_brick:. Bác nào biết cái này chỉ mình với. App mình không dùng reactive nhé

Bash:
javax.enterprise.context.ContextNotActiveException
        at io.quarkus.arc.impl.ClientProxies.getDelegate(ClientProxies.java:40)
        at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.arc$delegate(RequestScopedSessionHolder_ClientProxy.zig:42)
        at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.getOrCreateSession(RequestScopedSessionHolder_ClientProxy.zig:102)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.acquireSession(TransactionScopedSession.java:104)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.createQuery(TransactionScopedSession.java:344)
        at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createQuery(ForwardingSession.java:168)
        at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createQuery(ForwardingSession.java:47)
        at org.hibernate.Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.createQuery(Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.zig:1916)
        at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:339)
        at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:315)
        at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:260)
        at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
        at io.engine.executor.Worker.doJob$lambda-5(Worker.kt:86)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onNext(ObservableDoOnEach.java:93)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:63)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:66)
        at io.lucy.engine.SubdomainEngine.execute$lambda-1(SubdomainEngine.kt:38)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
        at io.reactivex.rxjava3.core.Observable.subscribe(Observable.java:13099)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
        at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:41)
        at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:28)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)
 
Mình đang migrate app spring qua quarkus mà gặp một vấn đề liên quan đến transaction khi thực hiện query trong một thread khác như này

Mình có 1 api start job. Khi gửi start job, api cứ trả về true thôi còn job sẽ được chạy backgroud vì nó mất nhiều thời gian (mình đang sử dụng rxjava để chạy job). Trong quá trình chạy job thì sẽ sử dụng PanacheEntity để update trạng thái của job. Vì nó thực hiện transaction ở một thread khác nên nó bị lỗi như bên dưới :beat_brick:. Bác nào biết cái này chỉ mình với. App mình không dùng reactive nhé

Bash:
javax.enterprise.context.ContextNotActiveException
        at io.quarkus.arc.impl.ClientProxies.getDelegate(ClientProxies.java:40)
        at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.arc$delegate(RequestScopedSessionHolder_ClientProxy.zig:42)
        at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.getOrCreateSession(RequestScopedSessionHolder_ClientProxy.zig:102)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.acquireSession(TransactionScopedSession.java:104)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.createQuery(TransactionScopedSession.java:344)
        at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createQuery(ForwardingSession.java:168)
        at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createQuery(ForwardingSession.java:47)
        at org.hibernate.Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.createQuery(Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.zig:1916)
        at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:339)
        at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:315)
        at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:260)
        at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
        at io.engine.executor.Worker.doJob$lambda-5(Worker.kt:86)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onNext(ObservableDoOnEach.java:93)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:63)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:66)
        at io.lucy.engine.SubdomainEngine.execute$lambda-1(SubdomainEngine.kt:38)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
        at io.reactivex.rxjava3.core.Observable.subscribe(Observable.java:13099)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
        at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:41)
        at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:28)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)
Exception này quăng ra là do transaction context ko được PROPAGATION cho cái thread mà đoạn code này đang run. Nếu muốn sử dụng transaction ở thread khác thì bạn phải propagate cái transaction context đó. Nó có liên quan đến 1 feature của Quarkus : https://quarkus.io/guides/context-propagation. Bạn tham khảo thử nhé.
 
Exception này quăng ra là do transaction context ko được PROPAGATION cho cái thread mà đoạn code này đang run. Nếu muốn sử dụng transaction ở thread khác thì bạn phải propagate cái transaction context đó. Nó có liên quan đến 1 feature của Quarkus : https://quarkus.io/guides/context-propagation. Bạn tham khảo thử nhé.
À mình xử lý dc case này rồi. Những chỗ liên quan đến update database mình cho vào 1 method của 1 class @ApplicationScope
 
Back
Top