mysql 表锁和行锁下

可重复读:

幻读;

死锁:

----------------------------

可重复读:

A session 执行:

mysql 表锁和行锁下

 

B sesion 执行:

mysql 表锁和行锁下

3)BSession执行后,查看A执行

 

mysql 表锁和行锁下

 

(4)在客户端A,接着执行update account set balance = balance - 50
where id = 1,balance没有变成400-50=350,lilei的balance值用的是步骤
(2)中的350来算的,所以是300,数据的一致性倒是没有被破坏。可重复读的
隔离级别下使用了MVCC(multi-version concurrency control)机制,select操作
不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本
号,是当前读(当前版本)。

mysql 表锁和行锁下

 

 

5)

 

mysql 表锁和行锁下

 

 

mysql 表锁和行锁下

串行化使用频率低不再赘述。

 

Mysql默认级别是repeatable-read,有办法解决幻读问题吗?
 
要避免幻读可以用间隙锁在Session_1下面执行update account set name =
'aaa' where id > 10 and id <=20;,则其他Session没法在这个范围所包含的
间隙里插入或修改任何数据.
 
无索引行锁会升级为表锁:锁主要是加在索引上,如果对非索引字 段更新, 行锁可能会变表锁 session1执行: update account set balance = 800 where name = 'lilei'; session2对该表任一行操作都会阻塞住 InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失 效,否则都会从行锁升级为表锁。
 
死锁:
 
set tx_isolation='repeatable-read';
Session_1执行:select * from account where id=1 for update;
Session_2执行:select * from account where id=2 for update;
Session_1执行:select * from account where id=2 for update;
Session_2执行:select * from account where id=1 for update;
查看近期死锁日志信息:show engine innodb status;
 
 
2.2.6 优化建议
尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁 合理设计索引,尽量缩小锁的范围 尽可能减少检索条件范围,避免间隙锁 尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql 尽量放在事务最后执行 尽可能低级别事务隔离