RT,
id 是自增主键,自己在本地 begin work 的方式开启多个事务,分别执行上面这一条语句,那这条 sql 会有并发问题吗?
看网上很多人说这条语句是先查到 a 的值再去计算最后 update 掉的。然鹅自己试的结果似乎并没有出现值覆盖的问题- -。
即便是 READ_UNCOMMIT 隔离下,开三个事务:
事务 A 提交了 update 之后,虽然事务 B、事务 C 均可以查到 A 未提交的值; 事务 B、事务 C 分别提交自己的 update,等待行锁; A 手动提交,B、C 分别手动提交;
发现最后似乎也没有出现 B C 拿同一个值去 update 的现象,a 最后的值是减了 3 的
mysql 不怎么熟悉,所以这种事务内的 update 语句,是会先拿到行锁再去取值的么?还是说要怎么操作才能出现异常 case ?有没有大佬可以指教下?
1
fmumu 2018-07-30 20:52:46 +08:00 via Android
update table set a=a-1 这个操作是原子性的,不会出现你想象的那种异常吧
|
2
metrxqin 2018-07-30 23:19:00 +08:00
官方文档特别提到这个行为:
Using READ COMMITTED has additional effects: For UPDATE or DELETE statements, InnoDB holds locks only for rows that it updates or deletes. Record locks for nonmatching rows are released after MySQL has evaluated the WHERE condition. This greatly reduces the probability of deadlocks, but they can still happen. For UPDATE statements, if a row is already locked, InnoDB performs a “ semi-consistent ” read, returning the latest committed version to MySQL so that MySQL can determine whether the row matches the WHERE condition of the UPDATE. If the row matches (must be updated), MySQL reads the row again and this time InnoDB either locks it or waits for a lock on it. https://dev.mysql.com/doc/refman/5.5/en/innodb-transaction-isolation-levels.html UPDATE 操作不会使用快照值,所以不会有覆盖更新的问题。 |