并发事务带来的问题
问题 | 含义 |
丢失更新( Lost Update ) | 当两个或多个事务选择同一行 ,最初的事务修改的值,会被后面的事务修改的值覆盖。 |
脏读( Dirty Reads ) | 当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。 |
不可重复读( Non-Repeatable Reads) | 一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现和以前读出的数据不一致。 |
幻读( Phantom Reads ) | 一个事务按照相同的查询条件重新读取以前查询过的数据,却发现其他事务插入了满定其查询条件的新数据。 |
事务隔离级别
隔离级别 | 丢失更新 | 脏读 | 不可重复读 | 幻读 |
read uncommitted | no | yes | yes | yes |
read committed | no | no | yes | yes |
repeatable read(default) | no | no | no | yes |
serializable | no | no | no | no |
锁分类
- 按对数据的操作粒度分:
- 表锁:锁定整个表。
- 行锁:锁定当前行。
- 对数据的操作类型分:
- 读锁
- 写锁
MyISAM 锁
显示加表锁
lock table tab_name read;
lock table tab_name write;
[SQL] ... lock in share mode;
[SQL] ... for update;
解锁
unlock tab_name;
查看表锁情况
show open tab_name;
InnoDB 锁
间隙锁危害
当我们用范围条件,而不是使用相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据进行加锁;对于键值在条件范围内但并不存在的记录,叫做"间隙",InnoDB也会对这个"间隙”加锁,这种锁机制就是所谓的间隙锁( Next-Key锁)。
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面
要远远由于MyISAM的表锁的。当系统并发量较高的时候, InnoDB的整体性能和MyISAM相比就会有比较明显的优势。
但是, InnoDB的行级锁同样也有其脆弱的- -面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可
能会更差。
优化建议:
- 尽可能让所有数据检索都能通过索引来完成,避免无索引行锁升级为表锁。
- 合理设计索引,尽量缩小锁的范围
- 尽可能减少索弓|条件,及索引范围,避免间隙锁
- 尽量控制事务大小,减少锁定资源量和时间长度
- 尽可使用低级别事务隔离(但是需要业务层面满足需求)