游网站建设方案内容,网站建设方维,中国建设银行官方网站汇率,嘉兴白酒网站建设目录
1.概述
2.事务
2.1.什么是事务
2.2.事务的隔离级别
2.2.1.三种数据一致性问题
2.2.2.四种隔离级别
2.3.如何设置隔离级别
3.锁
3.1.锁与事务的关系
3.2.分类
3.3.表锁
3.3.1.概述
3.3.2.读锁
3.3.3.写锁
3.3.4.保护机制
3.4.行锁
3.4.1.概述
3.4.2.什么…目录
1.概述
2.事务
2.1.什么是事务
2.2.事务的隔离级别
2.2.1.三种数据一致性问题
2.2.2.四种隔离级别
2.3.如何设置隔离级别
3.锁
3.1.锁与事务的关系
3.2.分类
3.3.表锁
3.3.1.概述
3.3.2.读锁
3.3.3.写锁
3.3.4.保护机制
3.4.行锁
3.4.1.概述
3.4.2.什么是MVCC
3.4.3.mvcc的使用
3.4.4.间隙锁
3.4.5.行锁变表锁 1.概述
所谓的并发控制就是规避多个会话并发访问数据库带来的诸如脏数据之类的数据一致性问题MySQL中提供了一系列的机制让我们可以去进行并发控制。
本质上来说MySQL就是用的两种锁来进行并发控制一种是表锁锁住整张表一种是行锁锁住某个数据行。
平时我们使用的时候很少会直接去操作锁因为MySQL已经帮我们封装的很好了直接用innodb引擎事务就能很好的进行并发控制事务底层其实依赖的就是行锁。
本文会先聊事务、再聊表锁、行锁但其实总的来说MySQL进行并发控制就是行锁和表锁事务的底层用的就是行锁只是事务太重要了所以单独拎出来作为一个独立的章节聊。
2.事务
2.1.什么是事务
注意只有innodb引擎是支持事务的所以本文与事务相关的讨论默认都是在innodb引擎下。
在实际使用中会存在这样一类场景我们希望几条SQL要么同时执行成功要么同时失败不能有的成功有的失败。
比如网购下单生成订单、扣减库存两条SQL必须保证要么全部成功要么全部失败不能说生成订单成功但是扣减库存失败了或者说扣减库存成功但是生成订单失败了以上任何一种情况都是会产生脏数据的。如果两者中有一者失败另外一个也需要跟着执行不成功从而保证数据的正确性。
事务就是为了满足将多条捆绑在一起同成功同失败而出现的。人们在实现事务过程中发现事务要实现上面我们说的效果那么就必须实现四点
原子性Atomicity一致性Consistent隔离性Isolation持久性Durable
也就是大名鼎鼎的ACID很多地方称其为事务的四大特性。
1.原子性
事务是一个原子操作单元其对数据的修改要么全部执行要么全部不执行。
2.一致性
数据库中的数据总是从一个状态到另一个状态不能存在中间状态。继续以网购下单为例一开始的数据库中的数据为A状态执行完事务扣减库存、新增订单后的数据状态为B状态数据库只能由A到B不能出现诸如扣了库存没生成订单或者生成了订单没扣库存这样的中间状态。
3.隔离性
一个事务在提交之前其所做的修改对其它事务来说是不可见的。不保证隔离性会产生脏数据这个很好理解举个例子
A的银行账户有400有两个事务彼此之间数据可见也就是一个事务修改数据不管提没提交其他事务都看得见。
事务1A向B转200
A的账户扣减200B的账户新增200
事务2A向C转200
A的账户扣减200C的账户新增200
如果在事务1中的1、2步的时间间隙内事务2间插执行完毕那么在事务1第2步执行前A的账户中已经被扣减了两次200余额为0C的账户中多了200。
这时候如果在事务1的第2步中出错了、回滚那么A的账户又会回到事务1第一步执行之前的状态也就是A的账户又恢复成了400。最后C的账户平白无故多了200。
4.持久性
事务完成后其对数据的修改是永久的即使系统断电、重启也不会变。
2.2.事务的隔离级别
2.2.1.三种数据一致性问题
在没有隔离性的情况下事物之间会出现3种数据一致性问题
脏读事务A读取了事务B更新的数据然后B回滚操作那么A读取到的数据是脏数据不可重复读事务 A 多次读取同一数据事务 B 在事务A多次读取的过程中对数据作了更新并提交导致事务A多次读取同一数据时结果 不一致。幻读系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级但是系统管理员B就在这个时候插入了一条具体分数的记录当系统管理员A改结束后发现还有一条记录没有改过来就好像发生了幻觉一样这就叫幻读。
2.2.2.四种隔离级别
隔离级别可理解为隔离性的严格度MySQL并不是固定死了各个事务间就是不可读的而是规定了各种强度的隔离级别。
观察上面3种数据一致性问题就会发现解决它们需要的隔离性是递增的MySQL一共给出4种隔离级别隔离性也是递增的对应解决以上3个问题有3种加上1种3种问题都能覆盖解决的 Read Uncommitted读未提交最低的隔离级别允许一个事务读取另一个事务尚未提交的数据变更。可能导致脏读Dirty Read问题。 Read Committed读已提交确保一个事务只能读取另一个事务已经提交的数据变更。防止脏读问题但可能导致不可重复读Non-repeatable Read问题。 Repeatable Read可重复读确保在同一个事务中多次读取同一数据时能够得到一致的结果。防止脏读和不可重复读问题但可能导致幻读Phantom Read问题。 Serializable串行化最高的隔离级别强制事务串行执行确保不会发生脏读、不可重复读和幻读问题。但是并发性能较差通常不建议在高并发环境中使用。
2.3.如何设置隔离级别
可以在连接字符串中设置隔离级别
jdbc:mysql://localhost/mydatabase?useSSLfalsecharacterEncodingutf8transactionIsolation隔离级别可以通过SQL在会话中设置隔离级别
SET TRANSACTION ISOLATION LEVEL 隔离级别;3.锁
3.1.锁与事务的关系
锁是计算机协调多个进程或线程并发访问某一资源的机制用来解决并发访问带来的数据一致性问题。在数据库中除传统的计算资源如CPU、IO、RAM的争用以外数据更是会被并发访问的资源。所以MySQL数据库也用锁机制来保证数据并发访问的一致性。
不同的隔离级别底层就是用不同的锁来实现的。
3.2.分类
MySQL的锁可以从两种维度来分
一个维度是按照锁的是一行还是锁的是整张表分为
行锁表锁
另一个维度是按照锁的操作是读操作还是写操作分为
读锁写锁
3.3.表锁
3.3.1.概述
MySQL中innodb引擎和myisam引擎均支持用lock tables指令来锁表。
3.3.2.读锁
读锁一种共享锁针对被锁表所有会话都可以进行读操作所有会话都无法进行写操作。加锁方和其他客户端的区别是加锁方直接不允许进行写操作而其他会话的写操作允许进行只是会被阻塞挂起。锁解开后所有挂起的操作线程会去重新争抢资源。
加锁指令
lock tables 表名 read;
释放锁指令
unlock tanles;
加锁方不允许进行写操作 其它客户端的写操作在加锁方释放锁之前都被挂起 3.3.3.写锁
写锁排它锁针对被锁表加锁方可以读写其他会话的写操作会直接失败读操作会被阻塞挂起解锁以后被挂起的线程会重新去争抢资源。
加锁指令
lock tables 表名 write;
其它会话的读操作、写操作在加锁方释放锁之前都被阻塞挂起 3.3.4.保护机制
读锁、写锁中加锁方都只能读当前被自己锁定的表这是MySQL的一个保护机制为的就是强制要求加锁方给出一个说法到底准备锁多久不给说法不让走。 3.4.行锁
3.4.1.概述
innodb和myIsam最大的不同有两点一是支持事务二是支持行级锁。
3.4.2.什么是MVCC
行锁没有显式的声明办法而是藏在默认实现中MVCC 是 MySQL InnoDB 存储引擎的默认并发控制机制其采用的就是表锁。
并发控制有几种处理方法
第一种 基于锁的并发控制程序员B开始修改数据时给这些数据加上锁程序员A这时再读就发现读取不了处于等待情况只能等B操作完才能读数据这保证A不会读到一个不一致的数据但是这个会影响程序的运行效率。
第二种MVCC每个用户连接数据库时看到的都是某一特定时刻的数据库快照在B的事务没有提交之前A始终读到的是某一特定时刻的数据库快照不会读到B事务中的数据修改情况直到B事务提交才会读取B的修改内容。
MVCC其实就是实现事务的关键后续会有文章专门深入聊事务的实现此处暂不展开。
3.4.3.mvcc的使用
首先有一个需要纠正的是很多地方都说mvcc是通过手动提交来触发的这是个误导不管手动提交还是自动提交MVCC机制都是生效的只是手动提交用来观察mvcc过程更加直观。
此处为了直观我们也以手动提交为例首先通过set autocommit0可以关闭自动提交。关闭后每次执行sql以后通过commit命令来手动提交才会对数据库产生影响否则只会对当前操作方的数据快照有影响。innodb引擎中其他客户端想查看到最新的数据情况也必须通过commit指令来做一次同步因为innodb默认隔离级别为可重复读。
当一个会话修改某行数据未commit前其他会话对该行数据的修改会阻塞挂起直到先改那个会话commit为止。 3.4.4.间隙锁
使用范围条件匹配时innodb会给符合条件的已有数据记录的索引加“范围锁”范围锁是特殊的行锁对于键值在条件范围内但并不存在的记录叫做间隙GAPinnodb也会对这个间隙加锁这种机制叫做“间隙锁”。 3.4.5.行锁变表锁
任何需要全表扫描的情况时行锁都会升级为表锁。
因为MySQL不知道到底该锁哪行所以会将整个表都锁起来然后再进行全表扫描。
全表扫描的情况无非两种
没建索引。索引失效。