You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keycloak事务提交报错:当前线程无关联事务的原因排查求助

Keycloak自定义模块事务提交报错:No transaction associated with the current thread

环境信息

  • Keycloak版本:4.4.0.21-SNAPSHOT
  • 模块POM配置:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
    <artifactId>keycloak-parent</artifactId>
    <groupId>org.keycloak</groupId>
    <version>4.4.0.21-SNAPSHOT</version>
</parent>

<name>Keycloak WildFly Integration</name>
<description/>
<modelVersion>4.0.0</modelVersion>

<artifactId>keycloak-wildfly-parent</artifactId>
<packaging>pom</packaging>

<modules>
    <module>adduser</module>
    <module>extensions</module>
    <module>server-subsystem</module>
</modules>
</project>

参考实现(来自KeycloakApplications类)

KeycloakSession session = sessionFactory.create();
try {
    session.getTransactionManager().begin();
    //do some work with db etc.
    session.getTransactionManager().commit();
    ServicesLogger.LOGGER.addUserSuccess(userRep.getUsername(), realmRep.getRealm());
}

自定义模块代码

try {
    KeycloakTransactionManager transactionManager = session.getTransactionManager();
    transactionManager.begin();
    //do some work
    transactionManager.commit(); //error in this line
}

报错信息

java.lang.IllegalStateException: No transaction associated with the current thread

完整堆栈跟踪

15:23:36,668 ERROR [com.mycompany.sso.events.listener.KafkaConsumerProvider] (keycloak-audit-akka.actor.default-dispatcher-5) No transaction associated with the current thread: java.lang.IllegalStateException: No transaction associated with the current thread
at org.wildfly.transaction.client.ContextTransactionManager.commit(ContextTransactionManager.java:69)
at org.keycloak.transaction.JtaTransactionWrapper.commit(JtaTransactionWrapper.java:92)
at org.keycloak.services.DefaultKeycloakTransactionManager.commit(DefaultKeycloakTransactionManager.java:136)
at com.mycompany.sso.events.listener.KafkaConsumerProvider.process(KafkaConsumerProvider.java:79)
at akka.stream.javadsl.Source.$anonfun$map$1(Source.scala:1299)
at akka.stream.impl.fusing.Map$$anon$1.onPush(Ops.scala:54)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:523)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:480)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:376)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:606)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:485)
at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:581)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:749)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:764)
at akka.actor.Actor.aroundReceive(Actor.scala:539)
at akka.actor.Actor.aroundReceive$(Actor.scala:537)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:671)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:614)
at akka.actor.ActorCell.invoke(ActorCell.scala:583)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
at akka.dispatch.Mailbox.run(Mailbox.scala:229)
at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

调试情况

已调试org.keycloak.services.DefaultKeycloakTransactionManager类的begin()、commit()和rollback()方法,未定位到问题,同时保存了三个调试状态截图:

  • begin()前的TransactionManager状态
  • begin()后的TransactionManager状态
  • 执行完业务逻辑、commit()前的TransactionManager状态

错误原因分析

从堆栈信息可以看到,代码运行在Akka的异步调度线程(keycloak-audit-akka.actor.default-dispatcher-5)中,结合Keycloak的事务实现逻辑,问题根源在于:

  1. 线程绑定的事务上下文丢失
    Keycloak基于WildFly的ContextTransactionManager实现事务管理,该管理器依赖当前线程绑定的事务上下文。而Akka的线程池是异步非阻塞模型,若业务逻辑中存在异步操作、线程切换(比如Future回调、异步IO),会导致commit()时的线程和begin()时绑定事务的线程不一致,此时新线程无法找到关联的事务,触发报错。

  2. Keycloak Session的线程不安全特性
    Keycloak的KeycloakSession设计为线程不安全,不能在多线程环境下共享或切换线程使用。如果业务逻辑中跨线程操作了同一个Session,会导致Session内部的事务上下文被破坏,进而丢失事务关联。

  3. 隐式事务终止
    业务逻辑中的某些操作可能隐式终止了事务,比如调用了rollback()、事务超时,或者Session被意外销毁/重置,也会导致commit()时找不到关联事务。

对比参考代码:KeycloakApplications中的代码是在同步线程中执行,没有线程切换,事务上下文可以一直绑定在当前线程,因此能正常提交。

内容的提问来源于stack exchange,提问作者Pavel Bukhalov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 08:35:36