func (st *TxnState) GoString() string {
	var s strings.Builder
	s.WriteString("Txn{")
	if st.pending() {
		s.WriteString("state=pending")
	} else if st.Valid() {
		s.WriteString("state=valid")
		fmt.Fprintf(&s, ", txnStartTS=%d", st.Transaction.StartTS())
		if st.stmtBuf.Len() != 0 {
			fmt.Fprintf(&s, ", buf.length: %d, buf.size: %d", st.stmtBufLen(), st.stmtBufSize())
		}
	} else {
		s.WriteString("state=invalid")
	}
	s.WriteString("}")
	return s.String()
}
GoString implements the "%#v" format for fmt.Printf.
package session
import (
	"bytes"
	"context"
	"crypto/rand"
	"fmt"
	"strings"
	"sync"
	"sync/atomic"
	"github.com/pingcap/errors"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/store/tikv/oracle"
	"github.com/pingcap/tidb/tablecodec"
	"github.com/pingcap/tidb/util/logutil"
	"github.com/zhihu/zetta/tablestore/config"
	"go.uber.org/zap"
)
var (
	_ kv.Transaction = (*TxnState)(nil)
)
type TxnStateOption struct {
	ReadOnly bool
	Single   bool
	isRawKV  bool
}
type TxnState struct {
	ID string
	kv.Transaction
	txnFuture *txnFuture
	stmtBuf kv.MemBuffer
	TxnOpt      TxnStateOption
	doNotCommit error
	mu          sync.Mutex
	inProgress  atomic.Value
	session *session
}
func (st *TxnState) init() {
}
func (st *TxnState) initStmtBuf() {
	if st.stmtBuf == nil {
		st.stmtBuf = st.Transaction.NewStagingBuffer()
	}
}
func (st *TxnState) stmtBufLen() int {
	if st.stmtBuf == nil {
		return 0
	}
	return st.stmtBuf.Len()
}
func (st *TxnState) stmtBufSize() int {
	if st.stmtBuf == nil {
		return 0
	}
	return st.stmtBuf.Size()
}
func (st *TxnState) stmtBufGet(ctx context.Context, k kv.Key) ([]byte, error) {
	if st.stmtBuf == nil {
		return nil, kv.ErrNotExist
	}
	return st.stmtBuf.Get(ctx, k)
}
func (st *TxnState) Size() int {
	size := st.stmtBufSize()
	if st.Transaction != nil {
		size += st.Transaction.Size()
	}
	return size
}
func (st *TxnState) Valid() bool {
	return st.Transaction != nil && st.Transaction.Valid()
}
func (st *TxnState) pending() bool {
	return st.Transaction == nil && st.txnFuture != nil
}
func (st *TxnState) validOrPending() bool {
	return st.txnFuture != nil || st.Valid()
}
func (st *TxnState) String() string {
	if st.Transaction != nil {
		return st.Transaction.String()
	}
	if st.txnFuture != nil {
		return "txnFuture"
	}
	return "invalid transaction"
}