Skip to content

🐛 Fix panic in Scan causing deadlock#7

Merged
x5iu merged 2 commits intomainfrom
fix/sqlx-panic-in-scan
Dec 16, 2025
Merged

🐛 Fix panic in Scan causing deadlock#7
x5iu merged 2 commits intomainfrom
fix/sqlx-panic-in-scan

Conversation

@x5iu
Copy link
Copy Markdown
Owner

@x5iu x5iu commented Dec 16, 2025

Summary

修复了在 Scan 过程中发生 panic 时导致死锁的问题。

问题描述

当结构体字段的 Scan 方法发生 panic 时,某些数据库驱动会在 Scan 过程中持有内部锁。如果在 panic 后执行 defer rows.Close()defer tx.Rollback(),会导致死锁。

解决方案

  1. Row.Scan: 移除 defer r.rows.Close(),改为在每个成功/错误路径上显式调用 Close()。这样当 rows.Scan() panic 时,不会尝试关闭 rows,panic 会正常传播。

  2. 生成的代码: 移除 defer tx.Rollback(),改为在每个错误返回点显式调用 tx.Rollback()。这样当 Scan 中 panic 后,不会尝试 rollback,panic 会正常传播到调用者。

设计原则

  • 不捕获 panic: 让 Scan 中的 panic 直接传播,调用者需要自己处理 panic
  • 避免 defer 中的数据库操作: 在可能 panic 的代码路径上不使用 defer 调用数据库操作

Test plan

  • 运行 ./test.sh 验证所有测试通过
  • 验证 panic 测试不再超时
  • 验证 panic 能正常传播到调用者

🤖 Generated with Claude Code

@x5iu x5iu force-pushed the fix/sqlx-panic-in-scan branch from c48b98e to c55401b Compare December 16, 2025 06:45
@x5iu x5iu changed the title 🐛 Fix panic in Scan causing deadlock with SQLite driver 🐛 Fix panic in Scan causing deadlock Dec 16, 2025
@x5iu x5iu force-pushed the fix/sqlx-panic-in-scan branch from c55401b to 3af368e Compare December 16, 2025 06:58
When a struct field's Scan method panics, database drivers may deadlock
if rows.Close() or tx.Rollback() is called afterwards. This is because
the driver holds internal locks during Scan that are not properly
released when a panic occurs.

This fix:
- Wraps rows.Scan() to catch panics and convert them to errors
- Adds scanPanicError type to wrap panic values as errors
- Adds IsScanPanicError() function to detect scan panic errors
- Modifies generated code to skip tx.Rollback() on scan panic errors
- Updates Row.Scan() and scanAny() to handle panic gracefully
- Avoids calling rows.Close() after a panic to prevent deadlock

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@x5iu x5iu force-pushed the fix/sqlx-panic-in-scan branch from 3af368e to 52326be Compare December 16, 2025 07:13
@x5iu x5iu merged commit cf87fe7 into main Dec 16, 2025
9 checks passed
@x5iu x5iu deleted the fix/sqlx-panic-in-scan branch December 16, 2025 15:16
x5iu added a commit that referenced this pull request Dec 16, 2025
When a struct field's Scan method panics, database drivers may deadlock
if rows.Close() or tx.Rollback() is called afterwards. This is because
the driver holds internal locks during Scan that are not properly
released when a panic occurs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants