func (s *session) Retry() error { s.retrying = true nh := s.history.clone() // Debug infos. if len(nh.history) == 0 { s.debugInfos[retryEmptyHistoryList] = true } else { s.debugInfos[retryEmptyHistoryList] = false } defer func() { s.history.history = nh.history s.retrying = false }() if forUpdate := s.Value(forupdate.ForUpdateKey); forUpdate != nil { return errors.Errorf("can not retry select for update statement") } var err error retryCnt := 0 for { s.resetHistory() s.FinishTxn(true) success := true for _, sr := range nh.history { st := sr.st // Skip prepare statement if !needRetry(st) { continue } log.Warnf("Retry %s", st.OriginText()) switch st.(type) { case *stmts.ExecuteStmt: _, err = runStmt(s, st, sr.params...) default: _, err = runStmt(s, st) } if err != nil { if kv.IsRetryableError(err) { success = false break } log.Warnf("session:%v, err:%v", s, err) return errors.Trace(err) } } if success { err = s.FinishTxn(false) if !kv.IsRetryableError(err) { break } } retryCnt++ if (s.maxRetryCnt != unlimitedRetryCnt) && (retryCnt >= s.maxRetryCnt) { return errors.Trace(err) } kv.BackOff(retryCnt) } return err }
func (s *session) Retry() error { variable.GetSessionVars(s).RetryInfo.Retrying = true nh := s.history.clone() // Debug infos. if len(nh.history) == 0 { s.debugInfos[retryEmptyHistoryList] = true } else { s.debugInfos[retryEmptyHistoryList] = false } defer func() { s.history.history = nh.history variable.GetSessionVars(s).RetryInfo.Retrying = false }() if forUpdate := s.Value(forupdate.ForUpdateKey); forUpdate != nil { return errors.Errorf("can not retry select for update statement") } var err error retryCnt := 0 for { variable.GetSessionVars(s).RetryInfo.Attempts = retryCnt + 1 s.resetHistory() log.Info("RollbackTxn for retry txn.") err = s.RollbackTxn() if err != nil { // TODO: handle this error. log.Errorf("rollback txn failed, err:%v", errors.ErrorStack(err)) } success := true variable.GetSessionVars(s).RetryInfo.ResetOffset() for _, sr := range nh.history { st := sr.st log.Warnf("Retry %s", st.OriginText()) _, err = runStmt(s, st) if err != nil { if kv.IsRetryableError(err) { success = false break } log.Warnf("session:%v, err:%v", s, err) return errors.Trace(err) } } if success { err = s.CommitTxn() if !kv.IsRetryableError(err) { break } } retryCnt++ if (s.maxRetryCnt != unlimitedRetryCnt) && (retryCnt >= s.maxRetryCnt) { return errors.Trace(err) } kv.BackOff(retryCnt) } return err }
func (s *session) Retry() error { if s.sessionVars.TxnCtx.ForUpdate { return errors.Errorf("can not retry select for update statement") } s.sessionVars.RetryInfo.Retrying = true defer func() { s.sessionVars.RetryInfo.Retrying = false }() nh := getHistory(s) var err error retryCnt := 0 for { PrepareTxnCtx(s) success := true s.sessionVars.RetryInfo.ResetOffset() for _, sr := range nh.history { st := sr.st txt := st.OriginText() if len(txt) > sqlLogMaxLen { txt = txt[:sqlLogMaxLen] } log.Warnf("Retry %s (len:%d)", txt, len(st.OriginText())) _, err = st.Exec(s) if err != nil { if s.isRetryableError(err) { success = false break } log.Warnf("session:%v, err:%v", s, err) return errors.Trace(err) } } if success { err = s.doCommit() if !s.isRetryableError(err) { break } } retryCnt++ if (s.maxRetryCnt != unlimitedRetryCnt) && (retryCnt >= s.maxRetryCnt) { return errors.Trace(err) } kv.BackOff(retryCnt) } return err }