用Jooq替换JDBC Template批量更新时Quickperf报goroutine异常
问题与现象
我正在将JDBC Template替换为jOOQ,用于数据库实体的批量更新操作。运行带有Quickperf注解(如@ExpectUpdate)的单元测试时出现异常:
- jOOQ配置的批量大小为100,更新650个实体时,预期会执行7次查询(650/100向上取整)
- 但测试未返回Quickperf的验证结果,反而输出了一堆Go语言的goroutine栈跟踪信息
测试输出的栈信息
goroutine 3133262 [select]: runtime.gopark(0xc013e1df90?, 0x2?, 0xd8?, 0xdd?, 0xc013e1df24?) /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc013e1dd90 sp=0xc013e1dd70 pc=0x85b496 runtime.selectgo(0xc013e1df90, 0xc013e1df20, 0xc00262e900?, 0x0, 0xc01adf8300?, 0x1) /usr/local/go/src/runtime/select.go:328 +0x7dc fp=0xc013e1ded0 sp=0xc013e1dd90 pc=0x86983c net/http.(*persistConn).writeLoop(0xc00607a240) /usr/local/go/src/net/http/transport.go:2392 +0xf5 fp=0xc013e1dfc8 sp=0xc013e1ded0 pc=0xad4c35 net/http.(*Transport).dialConn.func6() /usr/local/go/src/net/http/transport.go:1752 +0x26 fp=0xc013e1dfe0 sp=0xc013e1dfc8 pc=0xad1726 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc013e1dfe8 sp=0xc013e1dfe0 pc=0x8865c1 created by net/http.(*Transport).dialConn /usr/local/go/src/net/http/transport.go:1752 +0x1791 —————————— goroutine 3133490 [runnable, locked to thread]: runtime.cgocall(0x887ea0, 0xc0300abac0) /usr/local/go/src/runtime/cgocall.go:158 +0x4a fp=0xc025267a50 sp=0xc025267a18 pc=0x8248ea syscall.SyscallN(0x7ffab1585000?, {0xc025267ae8?, 0x3?, 0x0?}) /usr/local/go/src/runtime/syscall_windows.go:557 +0x109 fp=0xc025267ac8 sp=0xc025267a50 pc=0x8830c9 syscall.Syscall(0xc025267b28?, 0x851a25?, 0xd003e6?, 0xc025267b48?, 0x88030d?) /usr/local/go/src/runtime/syscall_windows.go:495 +0x3b fp=0xc025267b10 sp=0xc025267ac8 pc=0x882ddb syscall.Closesocket(0x880de5?) /usr/local/go/src/syscall/zsyscall_windows.go:1343 +0x5c fp=0xc025267b58 sp=0xc025267b10 pc=0x8d557c internal/poll.(*FD).destroy(0xc013f40a00) /usr/local/go/src/internal/poll/fd_windows.go:373 +0x9a fp=0xc025267b80 sp=0xc025267b58 pc=0x8f4bfa internal/poll.(*FD).decref(0x219eb330b48?) /usr/local/go/src/internal/poll/fd_mutex.go:213 +0x53 fp=0xc025267ba0 sp=0xc025267b80 pc=0x8f2833 internal/poll.(*FD).Close(0xc013f40a00) /usr/local/go/src/internal/poll/fd_windows.go:395 +0x69 fp=0xc025267bd0 sp=0xc025267ba0 pc=0x8f4ce9 net.(*netFD).Close(0xc013f40a00) /usr/local/go/src/net/fd_posix.go:37 +0x38 fp=0xc025267c00 sp=0xc025267bd0 pc=0x9f3538 net.(*conn).Close(0xc02d6ae218) /usr/local/go/src/net/net.go:207 +0x45 fp=0xc025267c30 sp=0xc025267c00 pc=0xa03d85 net/http.(*persistConn).closeLocked(0xc01d7acb40, {0xdebaa0, 0xc00005abe0}) /usr/local/go/src/net/http/transport.go:2714 +0x130 fp=0xc025267cb8 sp=0xc025267c30 pc=0xad64f0 net/http.(*persistConn).close(0xc00476e7d8?, {0xdebaa0?, 0xc00005abe0?}) /usr/local/go/src/net/http/transport.go:2699 +0xb0 fp=0xc025267d10 sp=0xc025267cb8 pc=0xad62f0 net/http.(*persistConn).readLoop.func1() /usr/local/go/src/net/http/transport.go:2061 +0x2d fp=0xc025267d40 sp=0xc025267d10 pc=0xad40ed net/http.(*persistConn).readLoop(0xc01d7acb40) /usr/local/go/src/net/http/transport.go:2236 +0xab6 fp=0xc025267fc8 sp=0xc025267d40 pc=0xad38b6 net/http.(*Transport).dialConn.func5() /usr/local/go/src/net/http/transport.go:1751 +0x26 fp=0xc025267fe0 sp=0xc025267fc8 pc=0xad1786 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc025267fe8 sp=0xc025267fe0 pc=0x8865c1 created by net/http.(*Transport).dialConn /usr/local/go/src/net/http/transport.go:1751 +0x173e ————————— goroutine 3117448 [semacquire]: runtime.gopark(0x3?, 0xc00a0f1c20?, 0x40?, 0x2b?, 0xc00a0f1c20?) /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00a0f1bd8 sp=0xc00a0f1bb8 pc=0x85b496 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:369 runtime.semacquire1(0xc00ceb3544, 0x80?, 0x3, 0x1) /usr/local/go/src/runtime/sema.go:150 +0x20f fp=0xc00a0f1c40 sp=0xc00a0f1bd8 pc=0x86a92f sync.runtime_SemacquireMutex(0x0?, 0x0?, 0xc02eb7f680?) /usr/local/go/src/runtime/sema.go:77 +0x25 fp=0xc00a0f1c70 sp=0xc00a0f1c40 pc=0x881b85 sync.(*Mutex).lockSlow(0xc00ceb3540) /usr/local/go/src/sync/mutex.go:171 +0x165 fp=0xc00a0f1cc0 sp=0xc00a0f1c70 pc=0x89e545 sync.(*Mutex).Lock(...) /usr/local/go/src/sync/mutex.go:90 net/http.(*Transport).removeIdleConn(0xc01defbcd8?, 0xdebaa0?) /usr/local/go/src/net/http/transport.go:1096 +0x56 fp=0xc00a0f1d10 sp=0xc00a0f1cc0 pc=0xacc2b6 net/http.(*persistConn).readLoop.func1() /usr/local/go/src/net/http/transport.go:2062 +0x3b fp=0xc00a0f1d40 sp=0xc00a0f1d10 pc=0xad40fb net/http.(*persistConn).readLoop(0xc02ce15e60) /usr/local/go/src/net/http/transport.go:2236 +0xab6 fp=0xc00a0f1fc8 sp=0xc00a0f1d40 pc=0xad38b6 net/http.(*Transport).dialConn.func5() /usr/local/go/src/net/http/transport.go:1751 +0x26 fp=0xc00a0f1fe0 sp=0xc00a0f1fc8 pc=0xad1786 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00a0f1fe8 sp=0xc00a0f1fe0 pc=0x8865c1 created by net/http.(*Transport).dialConn /usr/local/go/src/net/http/transport.go:1751 +0x173e
排查方向
- 环境冲突检查:Java测试环境中可能混入了Go语言进程或依赖(比如基于Go的代理、数据库模拟器),导致输出无关栈信息。排查测试运行时的进程列表,移除无关的Go相关组件。
- Quickperf兼容性验证:确认Quickperf版本对jOOQ批量操作的支持情况,尝试更新到最新版,或查看官方文档中关于jOOQ的适配说明。
- jOOQ配置有效性验证:在测试中开启jOOQ的SQL日志,手动确认实际执行的查询次数是否符合预期,排除配置未生效的可能。
- 构建插件排查:检查Maven/Gradle等构建工具的插件,确认是否有插件引入了Go相关依赖或触发了Go进程。
内容的提问来源于stack exchange,提问作者yangyuan
相关产品推荐
相关产品推荐

