yl32940 пре 3 недеља
родитељ
комит
8ab5c430e3
2 измењених фајлова са 14 додато и 8 уклоњено
  1. 9 6
      DB/driver/driver.go
  2. 5 2
      gormvrtx/dialector.go

+ 9 - 6
DB/driver/driver.go

@@ -1,11 +1,14 @@
 package vrtxsql
 
-// database/sql 驱动壳: 连接注册表 (同路径共享一个引擎 + 全局串行锁)、
-// Conn/Tx/Stmt/Rows 适配。引擎是单写者模型, 所有操作 (含事务全程) 由
-// shared 的容量1信号量串行化。锁获取尊重 ctx —— 排队等锁阶段可被超时/
-// 取消中断; 但引擎一旦开始执行便不可中途打断 (单写者, 调用方应串行化,
-// 建议 SetMaxOpenConns(1))。SELECT 结果集流式返回 (worker 回调 + channel),
-// 结果集 Close 前持续持锁。
+// database/sql 驱动壳: 连接注册表 (同路径共享一个引擎)、
+// Conn/Tx/Stmt/Rows 适配。引擎是一写多读模型:
+//   - shared.sem 容量 16: 允许多读者并行进入引擎; 写操作也走同一条通道,
+//     但 core.accMu.Lock() 会把并发写排他化 (Begin/Commit/DDL 持写锁)
+//   - 锁获取尊重 ctx —— 排队等锁阶段可被超时/取消中断
+//   - SELECT 结果集流式返回 (worker 回调 + channel), Close 前持续持锁
+//
+// 调用方建议 SetMaxOpenConns(16) (≥ semaphore 容量), 否则并发读会在
+// sql.DB 连接池层被串行化, 引擎内部的 RLock 优势发挥不出来。
 
 import (
 	"context"

+ 5 - 2
gormvrtx/dialector.go

@@ -65,7 +65,10 @@ func (d *Dialector) Name() string { return "vrtx" }
 // 引擎无版本概念, 打开时的 CRC/WAL 恢复即完整性校验。
 //
 // 两个引擎相关的适配点:
-//   - SetMaxOpenConns(1): 引擎是单写者模型, 连接池压成 1 让所有 SQL 串行;
+//   - SetMaxOpenConns(16): 引擎已是一写多读模型, 允许多个读者并发。
+//     写锁由 core.accMu.Lock() 排他保证 (Begin/Commit/DDL 拿写锁), 读锁
+//     由 core.accMu.RLock() 允许多读者并行 —— 连接池容量要 ≥ driver 层
+//     shared.sem (16), 否则并发读在 sql.DB 层就被串死了。
 //   - ConnPool 包一层 rewritePool: 内联 LIMIT/OFFSET 整数参数 (驱动解析器支持限定名)
 //     (旧解析器只认裸列名/字面量 LIMIT, 该包装让 GORM 的 SQL 形态稳定可用)。
 func (d *Dialector) Initialize(db *gorm.DB) error {
@@ -76,7 +79,7 @@ func (d *Dialector) Initialize(db *gorm.DB) error {
 	if err != nil {
 		return err
 	}
-	sqlDB.SetMaxOpenConns(1)
+	sqlDB.SetMaxOpenConns(16)
 
 	eng, err := vrtxsql.SharedDB(d.DSN)
 	if err != nil {