diff --git a/planner/core/point_get_plan.go b/planner/core/point_get_plan.go index fe0682186ef7e..b16a1b0a9db5e 100644 --- a/planner/core/point_get_plan.go +++ b/planner/core/point_get_plan.go @@ -156,7 +156,8 @@ func TryFastPlan(ctx sessionctx.Context, node ast.Node) Plan { // is disabled (either by beginning transaction with START TRANSACTION or by setting // autocommit to 0. If autocommit is enabled, the rows matching the specification are not locked. // See https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html - if ctx.GetSessionVars().InTxn() { + sessVars := ctx.GetSessionVars() + if !sessVars.IsAutocommit() || sessVars.InTxn() { fp.Lock = true fp.IsForUpdate = true } diff --git a/planner/core/point_get_plan_test.go b/planner/core/point_get_plan_test.go index 3ff3cf80f328c..eecffc3e6fa5b 100644 --- a/planner/core/point_get_plan_test.go +++ b/planner/core/point_get_plan_test.go @@ -171,25 +171,27 @@ func (s *testPointGetSuite) TestPointGetPlanCache(c *C) { func (s *testPointGetSuite) TestPointGetForUpdate(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("create table fu (id int primary key)") - tk.MustExec("insert into fu values (6)") - tk.MustQuery("select * from fu where id = 6 for update").Check(testkit.Rows("6")) + tk.MustExec("create table fu (id int primary key, val int)") + tk.MustExec("insert into fu values (6, 6)") // In autocommit mode, outside a transaction, "for update" doesn't take effect. - res := tk.MustQuery("explain select * from fu where id = 6 for update") - // Point_Get_1 1.00 root table:fu, handle:6 - opInfo := res.Rows()[0][3] - selectLock := strings.Contains(fmt.Sprintf("%s", opInfo), "lock") - c.Assert(selectLock, IsFalse) + checkUseForUpdate(tk, c, false) tk.MustExec("begin") - tk.MustQuery("select * from fu where id = 6 for update").Check(testkit.Rows("6")) - res = tk.MustQuery("explain select * from fu where id = 6 for update") - // Point_Get_1 1.00 root table:fu, handle:6 - opInfo = res.Rows()[0][3] - selectLock = strings.Contains(fmt.Sprintf("%s", opInfo), "lock") - c.Assert(selectLock, IsTrue) + checkUseForUpdate(tk, c, true) + tk.MustExec("rollback") + tk.MustExec("set @@session.autocommit = 0") + checkUseForUpdate(tk, c, true) tk.MustExec("rollback") +} + +func checkUseForUpdate(tk *testkit.TestKit, c *C, expectLock bool) { + res := tk.MustQuery("explain select * from fu where id = 6 for update") + // Point_Get_1 1.00 root table:fu, handle:6 + opInfo := res.Rows()[0][3] + selectLock := strings.Contains(fmt.Sprintf("%s", opInfo), "lock") + c.Assert(selectLock, Equals, expectLock) + tk.MustQuery("select * from fu where id = 6 for update").Check(testkit.Rows("6 6")) }