mysql 悲观锁 机制 请教

2022-11-28 14:55:42 +08:00
 hhhhhh123

问题 1.:悲观锁 运行机制 目前无法理解的是 假设 pk_money= 1 , 我每次运行都会+ 1 但是我没提交啊
不知道为什么他会每次 + 1 ,
不知道是我 sql 语法问题 还是啥 ?
难道每次运行的时候 会把没有提及的 sql 自动提交? 但是我已经关闭了自动提交 。

问题 2: 我想把 set pk_money=pk_money+1 这个 pk_money 等于上面的查询结果 然后在+ 1 这个应该怎么写啊? 同时是悲观锁。 怎么把 下面的 select 和 update 合并。

问题 3: 我不提交的话,我重新开个窗口 单独去运行

update user_basic_info set pk_money=pk_money+1 where uid=123456803;

是会被阻塞到超时。 说明这个悲观锁是起作用了。 但是不知道怎么解释第一个问题

set autocommit=0;
start transaction;
select `pk_money` from user_basic_info where uid=123456803 for update ;
update user_basic_info set pk_money=pk_money+1 where uid=123456803;
--  COMMIT;

不会放图片。。。。

set autocommit=0
> OK
> Time: 0.074s


start transaction
> OK
> Time: 0.077s


select `pk_money` from user_basic_info where uid=123456803 for update
> Affected rows: 0
> Time: 0.071s


update user_basic_info set pk_money=pk_money+1 where uid=123456803
> Affected rows: 1
> Time: 0.074s


--  COMMIT;
> OK
> Time: 0.071s

2014 次点击
所在节点    程序员
44 条回复
hhhhhh123
2022-11-30 09:39:55 +08:00
@Dlin mysql> select pk_money from user_basic_info where uid= 123456803;
+----------+
| pk_money |
+----------+
| 499 |
+----------+
1 row in set (0.00 sec)

mysql> begin; set autocommit=0; SELECT pk_money FROM user_basic_info WHERE uid = 123456803 for update ; UPDATE user_basic_info set pk_money=pk_money+1 where uid =123456803;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+----------+
| pk_money |
+----------+
| 499 |
+----------+
1 row in set (0.00 sec)

Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select pk_money from user_basic_info where uid= 123456803;
+----------+
| pk_money |
+----------+
| 500 |
+----------+
1 row in set (0.00 sec)

mysql>
hhhhhh123
2022-11-30 09:41:35 +08:00
@raysonlu 这个是一样的
mysql> select pk_money from user_basic_info where uid= 123456803;
+----------+
| pk_money |
+----------+
| 500 |
+----------+
1 row in set (0.00 sec)

mysql> set autocommit=0; begin; SELECT pk_money FROM user_basic_info WHERE uid = 123456803 for update ; UPDATE user_basic_info set pk_money=pk_money+1 where uid =123456803;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+----------+
| pk_money |
+----------+
| 500 |
+----------+
1 row in set (0.00 sec)

Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select pk_money from user_basic_info where uid= 123456803;
+----------+
| pk_money |
+----------+
| 501 |
+----------+
1 row in set (0.00 sec)

mysql>
hhhhhh123
2022-11-30 09:48:20 +08:00
@raysonlu @Dlin @raysonlu @all 兄弟们,算了 不搞了。 谢谢各位的解惑。 反正 代码中测试 commit 是没有问题的 。
raysonlu
2022-12-01 10:35:10 +08:00
@hhhhhh123 技术在于折腾,不要放弃。有点怀疑是不是数据库工具没有帮你真正开到第二个会话,可以在 update 之后,在另一个会话界面执行一下“SELECT pk_money FROM user_basic_info WHERE uid = 123456803 for update ;” 正常某个会话锁了某行,另一个会话再尝试加锁,就会出现阻塞等待,可以用这一点判断一下是否在新的会话中。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/898510

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX