Repository: pingcap/tidb
File: pkg/sessiontxn/staleread/provider.go (Go)

Code before:
	return &StalenessTxnContextProvider{
		sctx: sctx,
		is:   is,
		ts:   ts,
	}
}

// GetTxnInfoSchema returns the information schema used by txn
func (p *StalenessTxnContextProvider) GetTxnInfoSchema() infoschema.InfoSchema {
	return p.is
}

// GetTxnScope returns the current txn scope
func (p *StalenessTxnContextProvider) GetTxnScope() string {
	return p.sctx.GetSessionVars().TxnCtx.TxnScope
}

// GetReadReplicaScope returns the read replica scope
func (p *StalenessTxnContextProvider) GetReadReplicaScope() string {
	return config.GetTxnScopeFromConfig()
}

// GetStmtReadTS returns the read timestamp.
func (p *StalenessTxnContextProvider) GetStmtReadTS() (uint64, error) {
	// When autocommit disabled and not in txn, activate the txn here to make sure
	// subsequent reads can reuse the snapshot.
	if !p.sctx.GetSessionVars().IsAutocommit() && !p.sctx.GetSessionVars().InTxn() {
		if _, err := p.ActivateTxn(); err != nil {
			return 0, err
		}
		p.sctx.GetSessionVars().SetInTxn(true)
	}
	return p.ts, nil
}

// GetStmtForUpdateTS will return an error because stale read does not support it
func (p *StalenessTxnContextProvider) GetStmtForUpdateTS() (uint64, error) {
	return 0, errors.New("GetForUpdateTS not supported for stalenessTxnProvider")
}

// OnInitialize is the hook that should be called when enter a new txn with this provider
func (p *StalenessTxnContextProvider) OnInitialize(ctx context.Context, tp sessiontxn.EnterNewTxnType) error {
	p.ctx = ctx
	switch tp {
	case sessiontxn.EnterNewTxnDefault, sessiontxn.EnterNewTxnWithBeginStmt:
		return p.activateStaleTxn()
	case sessiontxn.EnterNewTxnWithReplaceProvider:
		return p.enterNewStaleTxnWithReplaceProvider()
	default:
		return errors.Errorf("Unsupported type: %v", tp)
	}

Review comment (suggestion):
```suggestion
	// subsequent reads can reuse the snapshot.
	// This is to suport usage like:
        // set autocommit = 0;
        // select * fromt as of timestamp;
        // select statments; // using the same stale read ts
        // commit;
        // Related issue: https://github.com/pingcap/tidb/issues/64198
```

Code after:
	return &StalenessTxnContextProvider{
		sctx: sctx,
		is:   is,
		ts:   ts,
	}
}

// GetTxnInfoSchema returns the information schema used by txn
func (p *StalenessTxnContextProvider) GetTxnInfoSchema() infoschema.InfoSchema {
	return p.is
}

// GetTxnScope returns the current txn scope
func (p *StalenessTxnContextProvider) GetTxnScope() string {
	return p.sctx.GetSessionVars().TxnCtx.TxnScope
}

// GetReadReplicaScope returns the read replica scope
func (p *StalenessTxnContextProvider) GetReadReplicaScope() string {
	return config.GetTxnScopeFromConfig()
}

// GetStmtReadTS returns the read timestamp
func (p *StalenessTxnContextProvider) GetStmtReadTS() (uint64, error) {
	// When autocommit is disabled and in txn flag is flase, activate the txn here to make sure
	// subsequent reads can reuse the snapshot. This is to support usage like:
	//   set @@tidb_read_staleness = -1;
	//   set autocommit = 0;
	//   select x fromt t1; -- create a stale read ts
	//   select y from t2;  -- using the same stale read ts
	//   commit;
	// Related issue: https://github.com/pingcap/tidb/issues/64198
	if !p.sctx.GetSessionVars().IsAutocommit() && !p.sctx.GetSessionVars().InTxn() {
		if _, err := p.ActivateTxn(); err != nil {
			return 0, err
		}
		p.sctx.GetSessionVars().SetInTxn(true)
	}
	return p.ts, nil
}

// GetStmtForUpdateTS will return an error because stale read does not support it
func (p *StalenessTxnContextProvider) GetStmtForUpdateTS() (uint64, error) {
	return 0, errors.New("GetForUpdateTS not supported for stalenessTxnProvider")
}

// OnInitialize is the hook that should be called when enter a new txn with this provider
func (p *StalenessTxnContextProvider) OnInitialize(ctx context.Context, tp sessiontxn.EnterNewTxnType) error {
	p.ctx = ctx
	switch tp {
	case sessiontxn.EnterNewTxnDefault, sessiontxn.EnterNewTxnWithBeginStmt: