diff --git a/session/txnmanager.go b/session/txnmanager.go index 65652428f7481..0d72c89461237 100644 --- a/session/txnmanager.go +++ b/session/txnmanager.go @@ -51,7 +51,7 @@ type txnManager struct { ctxProvider sessiontxn.TxnContextProvider // We always reuse the same OptimisticTxnContextProvider in one session to reduce memory allocation cost for every new txn. - reservedOptimisticProvider isolation.OptimisticTxnContextProvider + reservedOptimisticProviders [2]isolation.OptimisticTxnContextProvider } func newTxnManager(sctx sessionctx.Context) *txnManager { @@ -241,8 +241,13 @@ func (m *txnManager) newProviderWithRequest(r *sessiontxn.EnterNewTxnRequest) (s switch txnMode { case "", ast.Optimistic: // When txnMode is 'OPTIMISTIC' or '', the transaction should be optimistic - m.reservedOptimisticProvider.ResetForNewTxn(m.sctx, r.CausalConsistencyOnly) - return &m.reservedOptimisticProvider, nil + provider := &m.reservedOptimisticProviders[0] + if old, ok := m.ctxProvider.(*isolation.OptimisticTxnContextProvider); ok && old == provider { + // We should make sure the new provider is not the same with the old one + provider = &m.reservedOptimisticProviders[1] + } + provider.ResetForNewTxn(m.sctx, r.CausalConsistencyOnly) + return provider, nil case ast.Pessimistic: // When txnMode is 'PESSIMISTIC', the provider should be determined by the isolation level switch sessVars.IsolationLevelForNewTxn() {