4、MySQL 事务隔离级别与锁机制
一、事务
原子性(Atomicity) :事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
一致性(Consistent) :在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性。
隔离性(Isolation) :数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
持久性(Durable) :事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
1.1、并发事务处理带来的问题
1.1.1、更新丢失(Lost Update)或脏写
1.1.2、脏读(Dirty Reads)
1.1.3、不可重复读(Non-Repeatable Reads)
1.1.4、幻读(Phantom Reads)
1.2、事务隔离级别
二、锁
2.1、锁分类
从性能上分为乐观锁和悲观锁。
从对数据库操作的类型分,分为读锁和写锁(都属于悲观锁)。
读锁(共享锁,S锁(Shared)):针对同一份数据,多个读操作可以同时进行而不会互相影响。
写锁(排它锁,X锁(eXclusive)):当前写操作没有完成前,它会阻断其他写锁和读锁。
从对数据操作的粒度分,分为表锁和行锁。
2.2、表锁
# 手动增加表锁 lock table 表名称1 read(write), 表名称2 read(write); # 查看表上加过的锁 show open tables; # 删除表锁 unlock tables;
2.3、行锁
InnoDB支持事务(TRANSACTION)
InnoDB支持行级锁。
2.3.1、行锁分析
show status like 'innodb_row_lock%';
查看INFORMATION_SCHEMA系统库锁相关数据表
-- 查看事务 select * from INFORMATION_SCHEMA.INNODB_TRX; -- 查看锁 select * from INFORMATION_SCHEMA.INNODB_LOCKS; -- 查看锁等待 select * from INFORMATION_SCHEMA.INNODB_LOCK_WAITS; -- 释放锁,trx_mysql_thread_id可以从INNODB_TRX表里查看到 kill trx_mysql_thread_id -- 查看锁等待详细信息 show engine innodb status\G;
2.4、间隙锁(Gap Lock)
2.4、临键锁(Next-key Locks)
2.5、死锁
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;
2.6、总结
无索引行锁会升级为表锁。
锁主要是加在索引上,如果对非索引字段更新,行锁可能会变表锁。
比如session1 执行:update account set balance = 800 where name = 'lilei'。session2 对该表任一行操作都会阻塞住。
InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁。
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会要更高一下,但是在整体并发处理能力方面要远远优于MYISAM的表级锁定的。当系统并发量高的时候,InnoDB的整体性能和MYISAM相比就会有比较明显的优势了。但是,InnoDB的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MYISAM高,甚至可能会更差。
2.7、锁优化建议
尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁。
合理设计索引,尽量缩小锁的范围。
尽可能减少检索条件范围,避免间隙锁。
尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql尽量放在事务最后执行。
尽可能低级别事务隔离。
版权声明
非特殊说明,本文由Zender原创或收集发布,欢迎转载。
ZENDER






发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。