Skip to content

Commit e5c9e5d

Browse files
committed
always rollback the transaction
Signed-off-by: Yang Keao <[email protected]>
1 parent 9c01dcd commit e5c9e5d

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

pkg/ttl/session/session.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,20 @@ func (s *session) ExecuteSQL(ctx context.Context, sql string, args ...any) ([]ch
111111

112112
// RunInTxn executes the specified function in a txn
113113
func (s *session) RunInTxn(ctx context.Context, fn func() error, txnMode TxnMode) (err error) {
114+
success := false
115+
defer func() {
116+
// Always try to `ROLLBACK` the transaction even if only the `BEGIN` fails. If the `BEGIN` is killed
117+
// after it runs the first `Next`, the transaction is already active and needs to be `ROLLBACK`ed.
118+
if !success {
119+
// For now, the "ROLLBACK" can execute successfully even when the context has already been cancelled.
120+
// Using another timeout context to avoid that this behavior will be changed in the future.
121+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
122+
_, rollbackErr := s.ExecuteSQL(ctx, "ROLLBACK")
123+
terror.Log(rollbackErr)
124+
cancel()
125+
}
126+
}()
127+
114128
tracer := metrics.PhaseTracerFromCtx(ctx)
115129
defer tracer.EnterPhase(tracer.Phase())
116130

@@ -129,14 +143,6 @@ func (s *session) RunInTxn(ctx context.Context, fn func() error, txnMode TxnMode
129143
}
130144
tracer.EnterPhase(metrics.PhaseOther)
131145

132-
success := false
133-
defer func() {
134-
if !success {
135-
_, rollbackErr := s.ExecuteSQL(ctx, "ROLLBACK")
136-
terror.Log(rollbackErr)
137-
}
138-
}()
139-
140146
if err = fn(); err != nil {
141147
return err
142148
}

pkg/ttl/ttlworker/scan_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,3 +554,21 @@ func TestScanTaskCancelStmt(t *testing.T) {
554554
task.ctx, cancel = context.WithCancel(context.Background())
555555
testCancel(context.Background(), cancel)
556556
}
557+
558+
// NewTTLScanTask creates a new TTL scan task for test.
559+
func NewTTLScanTask(ctx context.Context, tbl *cache.PhysicalTable, ttlTask *cache.TTLTask) *ttlScanTask {
560+
return &ttlScanTask{
561+
ctx: ctx,
562+
tbl: tbl,
563+
TTLTask: ttlTask,
564+
statistics: &ttlStatistics{},
565+
}
566+
}
567+
568+
// DoScan is an exported version of `doScan` for test.
569+
func (t *ttlScanTask) DoScan(ctx context.Context, delCh chan<- *TTLDeleteTask, sessPool util.SessionPool) *ttlScanTaskExecResult {
570+
return t.doScan(ctx, delCh, sessPool)
571+
}
572+
573+
// TTLDeleteTask is an exported version of `ttlDeleteTask` for test.
574+
type TTLDeleteTask = ttlDeleteTask

0 commit comments

Comments
 (0)