| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package main
- import (
- "TsDB2/DB"
- "fmt"
- "os"
- "sync"
- "time"
- )
- type Record struct {
- DB.BaseModel
- Name string `tsdb:"32byte"`
- }
- const dbPath = "lock_table_test.db"
- func main() {
- fmt.Println("==============================================")
- fmt.Println(" 锁表机制测试")
- fmt.Println("==============================================\n")
- os.Remove(dbPath)
- db, err := DB.Open(dbPath)
- if err != nil {
- panic(err)
- }
- defer db.Close()
- tbl, err := DB.UseTable[Record](db, "test")
- if err != nil {
- panic(err)
- }
- // ========== 测试1: 手动锁表 ==========
- fmt.Println("测试1: 手动 LockWrites/UnlockWrites")
-
- db.LockWrites()
- fmt.Println(" ✅ 已锁定写入")
-
- // 尝试在另一个 goroutine 中插入(应该阻塞)
- var wg sync.WaitGroup
- insertSuccess := false
-
- wg.Add(1)
- go func() {
- defer wg.Done()
- err := tbl.Insert(&Record{Name: "Emp0000001"})
- if err == nil {
- insertSuccess = true
- fmt.Println(" ❌ 锁定期不应允许插入")
- } else {
- fmt.Printf(" ✅ 插入被阻止: %v\n", err)
- }
- }()
-
- // 等待 100ms,确认 goroutine 已阻塞
- time.Sleep(100 * time.Millisecond)
- fmt.Println(" ⏳ 插入操作正在等待解锁...")
-
- // 解锁
- time.Sleep(200 * time.Millisecond)
- db.UnlockWrites()
- fmt.Println(" ✅ 已解锁写入")
-
- wg.Wait()
- if insertSuccess {
- fmt.Println(" ❌ 测试失败: 锁定期插入了数据")
- } else {
- fmt.Println(" ✅ 测试通过: 锁定期成功阻止写入")
- }
-
- // ========== 测试2: Commit 期间自动锁表 ==========
- fmt.Println("\n测试2: Commit 期间自动锁表")
-
- // 插入一些数据
- for i := 1; i <= 100; i++ {
- tbl.Insert(&Record{Name: fmt.Sprintf("Emp%07d", i)})
- }
- fmt.Println(" 已插入 100 行")
-
- // 在另一个 goroutine 中尝试插入
- wg.Add(1)
- commitBlocked := false
-
- go func() {
- defer wg.Done()
- start := time.Now()
- err := tbl.Insert(&Record{Name: "Emp0000101"})
- elapsed := time.Since(start)
-
- if elapsed > 10*time.Millisecond {
- commitBlocked = true
- fmt.Printf(" ✅ 插入被 Commit 阻塞 (%v)\n", elapsed)
- }
- _ = err
- }()
-
- // 等待 goroutine 启动
- time.Sleep(50 * time.Millisecond)
-
- // 执行 Commit(会自动锁表)
- fmt.Println(" 执行 Commit...")
- db.Commit()
- fmt.Println(" ✅ Commit 完成")
-
- wg.Wait()
-
- if commitBlocked {
- fmt.Println(" ✅ 测试通过: Commit 期间成功阻止写入")
- } else {
- fmt.Println(" ⚠️ 未检测到阻塞(可能 Commit 太快)")
- }
-
- // ========== 测试3: BufferPool 满时阻塞等待 ==========
- fmt.Println("\n测试3: BufferPool 满时阻塞等待")
-
- // 设置很小的容量 (10页)
- db2, _ := DB.Open("lock_test2.db")
- defer db2.Close()
- os.Remove("lock_test2.db")
-
- db2.SetBufferPoolCapacity(10) // 只允许10页
- tbl2, _ := DB.UseTable[Record](db2, "test")
-
- // 插入10行(填满 BufferPool)
- for i := 1; i <= 10; i++ {
- tbl2.Insert(&Record{Name: fmt.Sprintf("Emp%07d", i)})
- }
- fmt.Println(" 已插入 10 行(BufferPool 已满)")
-
- // 在另一个 goroutine 中尝试插入第11行(应该阻塞)
- var insertBlocked bool
- wg.Add(1)
- go func() {
- defer wg.Done()
- start := time.Now()
- tbl2.Insert(&Record{Name: "Emp0000011"})
- elapsed := time.Since(start)
-
- if elapsed > 50*time.Millisecond {
- insertBlocked = true
- fmt.Printf(" ✅ 插入被阻塞 (%v),等待空间释放\n", elapsed)
- }
- }()
-
- // 等待 goroutine 启动并阻塞
- time.Sleep(100 * time.Millisecond)
-
- // 执行 Commit,释放空间
- fmt.Println(" 执行 Commit 释放空间...")
- db2.Commit()
- fmt.Println(" ✅ Commit 完成,空间已释放")
-
- wg.Wait()
-
- if insertBlocked {
- fmt.Println(" ✅ 测试通过: BufferPool 满时正确阻塞等待")
- } else {
- fmt.Println(" ⚠️ 未检测到阻塞(可能 Commit 太快)")
- }
-
- fmt.Println("\n==============================================")
- fmt.Println(" 所有测试完成!")
- fmt.Println("==============================================")
- }
|