| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- package core
- // 事务起始边界收敛的回归测试。
- //
- // 背景 (database/sql 驱动变异测试实锤): 自动提交挂起的未落盘插入 → BEGIN →
- // 事务内插入 → ROLLBACK → 再插入 —— "load failed"。根因: 回滚按 touched 丢弃
- // 页缓存时, 把这些页里【事务开始前】的未提交修改一起丢掉了, 而未被 touched 的
- // IndexMeta 页 (仍缓存着脏副本) 指向已被丢弃的树页 —— meta 指树、树已没了。
- // 修复: BeginTransaction 先把未提交脏页提交掉 (BEGIN = 此前工作已提交的边界)。
- import (
- "testing"
- "git.ycl.pub/yl32940/TsDB2/DB/core/page"
- "git.ycl.pub/yl32940/TsDB2/DB/core/types"
- )
- func TestBeginTransactionConvergesPendingWrites(t *testing.T) {
- // 与驱动同款环境: 自动提交默认开 (1s 防抖), 不手动收敛
- db, err := Open(t.TempDir() + "/begin_boundary.db")
- if err != nil {
- t.Fatal(err)
- }
- defer db.Close()
- tbl, err := db.CreateTable("t", []types.FieldInfo{
- {FieldType: types.FieldType_Int64, FieldName: []byte("id")},
- {FieldType: types.FieldType_Int64, FieldName: []byte("v")},
- })
- if err != nil {
- t.Fatal(err)
- }
- if _, err := tbl.CreateIndex("pk", page.IndexTypePrimary, []byte{0}); err != nil {
- t.Fatal(err)
- }
- // 自动提交挂起的插入 (不落盘)
- if _, err := tbl.InsertRowWithID(1, []types.FieldValue{
- {FieldName: []byte("id"), Value: int64(1)},
- {FieldName: []byte("v"), Value: int64(10)},
- }); err != nil {
- t.Fatal(err)
- }
- // BEGIN (收敛未提交修改) → 事务内插入 → ROLLBACK
- tx := db.BeginTransaction()
- if _, err := tbl.InsertRowWithID(2, []types.FieldValue{
- {FieldName: []byte("id"), Value: int64(2)},
- {FieldName: []byte("v"), Value: int64(20)},
- }); err != nil {
- t.Fatal(err)
- }
- if err := tx.Rollback(); err != nil {
- t.Fatal(err)
- }
- // 事务前的行必须还在 (Begin 时已收敛), 事务内的行必须没了
- if _, err := tbl.FindByPK(1); err != nil {
- t.Fatalf("事务前的行丢失: %v", err)
- }
- if _, err := tbl.FindByPK(2); err == nil {
- t.Fatalf("事务内的行未被回滚")
- }
- // 修复前的炸点: 回滚后再插入必须成功
- if _, err := tbl.InsertRowWithID(3, []types.FieldValue{
- {FieldName: []byte("id"), Value: int64(3)},
- {FieldName: []byte("v"), Value: int64(30)},
- }); err != nil {
- t.Fatalf("回滚后再插入: %v", err)
- }
- if _, err := tbl.FindByPK(3); err != nil {
- t.Fatalf("新插入不可见: %v", err)
- }
- }
|