MYSQL锁和事务机制

mysql基础:

mysql的四个特性,原子性、一致性、隔离性、持久性。
1.原子性(atomicity):一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。

2.一致性(consistency):数据库总数从一个一致性的状态转换到另一个一致性的状态。

3.隔离性(isolation):一个事务所做的修改在最终提交以前,对其他事务是不可见的。

4.持久性(durability):一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

—————————————————————————————————————

mysql引擎:

InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
不同引擎锁特性不同。
MYSQL锁和事务机制_第1张图片
图片.png

—————————————————————————————————————

mysql事务:

mysql事务就是一组原子性的SQL查询,或者说一个独立的工作逻辑单元,事务内的语句,要么全部执行成功,要么全部执行失败。

Innodb可实现中的事务隔离级别:


MYSQL锁和事务机制_第2张图片
图片.png

脏读: 当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。
非重复读:当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。
幻读:当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。
—————————————————————————————————————

mysql锁参考:

可以通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况

MySQL中锁的种类很多,有常见的表锁和行锁
  • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
  • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

行锁是锁住数据行,这种加锁方法比较复杂,但是由于只锁住有限的数据,对于其它数据不加限制,所以并发能力强,MySQL一般都是用行锁来处理并发事务。这里主要讨论的也就是行锁。

在表级锁和行锁都有以下两种类型:
  • 共享锁又称:读锁。当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上排它锁,但允许上读锁。

  • 排它锁又称:写锁。当一个事务对某几个上写锁时,不允许其他事务写,但允许读。更不允许其他事务给这几行上任何锁。包括写锁。

MySQL MyISAM(只有表锁)加锁机制:

在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,对表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对表的写操作,则会阻塞其他用户对同一表的读和写请求;

MySQL InnoDB默认[行级锁]也支持表锁。行级锁都是基于索引的,:

行级锁变为表级锁情况如下:
1、如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住。
2、表字段进行变更。
3、进行整表查询。(没使用索引)
4、like语句查询的时候。(没使用索引)

另外,为了允许行锁和表锁共存,实现多粒度锁机制,除了共享锁,排它锁两种行锁,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。____________所以innodb共有4种锁

  • 意向共享锁(IS):事务打算给数据行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
  • 意向排他锁(IX):事务打算给数据行加排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
MySQL InnoDB加锁机制:

对于意向锁,意向锁是InnoDB自动加的,不需用户干预。

对于非意向锁,UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及及数据行集加排他锁(X);对于普通SELECT语句,InnoDB不会任何锁;事务可以通过以下语句显示给记录集加共享锁或排锁。
事务可以通过以下语句显示给记录集加共享锁或排锁。
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE

锁机制拓展

乐观与悲观锁
乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了。

悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟java中的synchronized很相似,所以悲观锁需要耗费较多的时间。另外与乐观锁相对应的,悲观锁是由数据库自己实现了的,要用的时候,我们直接调用数据库的相关语句就可以了。

共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴。

你可能感兴趣的:(MYSQL锁和事务机制)