From d97a175513719e76fdd264f2721ce56648122a0a Mon Sep 17 00:00:00 2001 From: siddontang Date: Thu, 26 Nov 2015 12:59:21 +0800 Subject: [PATCH 1/2] tidb: err should rollback in auto commit or DDL. --- session.go | 1 - session_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ tidb.go | 8 ++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/session.go b/session.go index 60264a4ab6..ad932a86d9 100644 --- a/session.go +++ b/session.go @@ -95,7 +95,6 @@ func (h *stmtHistory) add(stmtID uint32, st stmt.Statement, params ...interface{ } func (h *stmtHistory) reset() { - if len(h.history) > 0 { h.history = h.history[:0] } diff --git a/session_test.go b/session_test.go index 5214d03978..c2ec056850 100644 --- a/session_test.go +++ b/session_test.go @@ -1176,3 +1176,45 @@ func (s *testSessionSuite) TestSession(c *C) { err := se.Close() c.Assert(err, IsNil) } + +func (s *testSessionSuite) TestErrorRollback(c *C) { + store := newStore(c, s.dbName) + s1 := newSession(c, store, s.dbName) + + defer s1.Close() + + mustExecSQL(c, s1, "drop table if exists t_rollback") + mustExecSQL(c, s1, "create table t_rollback (c1 int, c2 int, primary key(c1))") + + _, err := s1.Execute("insert into t_rollback values (0, 0)") + c.Assert(err, IsNil) + + var wg sync.WaitGroup + cnt := 10 + wg.Add(cnt) + num := 1000 + + for i := 0; i < cnt; i++ { + go func() { + defer wg.Done() + se := newSession(c, store, s.dbName) + // retry forever + se.(*session).maxRetryCnt = unlimitedRetryCnt + defer se.Close() + + for j := 0; j < num; j++ { + // force generate a txn in session for later insert use. + se.(*session).GetTxn(false) + + se.Execute("insert into t_rollback values (1, 1, 1)") + + _, err = se.Execute("update t_rollback set c2 = c2 + 1 where c1 = 0") + c.Assert(err, IsNil) + } + }() + } + + wg.Wait() + + mustExecMatch(c, s1, "select c2 from t_rollback where c1 = 0", [][]interface{}{{cnt * num}}) +} diff --git a/tidb.go b/tidb.go index 73df30ad20..6d166a3f8e 100644 --- a/tidb.go +++ b/tidb.go @@ -225,8 +225,12 @@ func runStmt(ctx context.Context, s stmt.Statement, args ...interface{}) (rset.R se.history.add(0, s) } // MySQL DDL should be auto-commit - if err == nil && (s.IsDDL() || autocommit.ShouldAutocommit(ctx)) { - err = ctx.FinishTxn(false) + if s.IsDDL() || autocommit.ShouldAutocommit(ctx) { + if err != nil { + ctx.FinishTxn(true) + } else { + err = ctx.FinishTxn(false) + } } return rs, errors.Trace(err) } From ebe1ff97fafd541d9c203fcac3e68df035ea83d4 Mon Sep 17 00:00:00 2001 From: shenli Date: Thu, 26 Nov 2015 13:58:29 +0800 Subject: [PATCH 2/2] tidb: Refactor GetTxn --- session.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/session.go b/session.go index ad932a86d9..61da119494 100644 --- a/session.go +++ b/session.go @@ -506,17 +506,10 @@ func (s *session) GetTxn(forceNew bool) (kv.Transaction, error) { return s.txn, nil } if forceNew { - err = s.txn.Commit() - variable.GetSessionVars(s).SetStatusFlag(mysql.ServerStatusInTrans, false) + err = s.FinishTxn(false) if err != nil { - if !s.retrying && kv.IsRetryableError(err) { - err = s.Retry() - } - if err != nil { - return nil, errors.Trace(err) - } + return nil, errors.Trace(err) } - s.resetHistory() s.txn, err = s.store.Begin() if err != nil { return nil, err