Mysql基本数据类型
MySQL-事务
1. 事务管理(ACID)
A原子性:
原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部完成,要么全部没有完成,具有原子性。
C一致性
事务前后数据的完整性必须保持一致。
I 隔离性:
事务的隔离性指的是多用户并发访问数据库时,数据库为不同的用户开启的事务,不能被其他事务操作数据所干扰,多个并发事务之间要相互隔离开。
D持久性:
持久性是指一个事务一旦提交,对数据库的改变时永久性,不可回退的,接下来数据库及时发生什么故障对前面提交的事务没有任何影响。
1.1 下面详细举例说明一下这四个点:
A原子性:
这个过程包含两个步骤
A: 800 - 200 = 600
B: 200 + 200 = 400
原子性表示,这两个步骤一起成功,或者一起失败,不能只发生其中一个动作
C一致性:
操作前A:800,B:200
操作后A:600,B:400
一致性表示事务完成后,符合逻辑运算
D持久性:
表示事务结束后的数据不随着外界原因导致数据丢失
操作前A:800,B:200
操作后A:600,B:400
如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为
A:800,B:200
如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为
A:600,B:400
I 隔离性:
针对多个用户同时操作,主要是排除其他事务对本次事务的影响
事务一)A向B转账200
事务二)C向B转账100
两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据,执行步骤如图所示,按照数字顺序执行
隔离性用于解决以上问题
2.1 事务的并发带来的问题
<1> 更新丢失:事务A和事务B选择同一行,然后基于最初选定的数据进行更新,此时由于两个事务都不知道对方的存在,就会发生丢失更新的问题。
<2> 脏读(读未提交):一个事务读取了另外一个事务未提交的数据,事务A读取了事务B更新的数据,然后B回滚操作,A读取到的就是脏数据。
<3> 不可重复读(读已提交):事务A多次读取统一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致,(主要是B对数据进行了更新操作,A读取到的数据不一样)
<4> 幻读(可重复读):和不可重复度类似,发生在事务A读取了几行数据,事务B此时插入或删除了部分数据,导致事务A在此读取数据时,导致读取的记录数不一致。(主要是B对数据进行了新增或删除操作,导致记录数不一致)
2.2 事务并发带来的问题的解决办法
<1>“更新丢失”通常是完全避免的,防止更新丢失,并不能单靠数据库事务控制来解决,需要应用程序对更新的数据加必要的锁来解决,因此,防止更新时应用的责任。
<2> “脏读”、“不可重复读”、“幻读”,都是数据库读不一致的问题,必须由数据库提供的事务隔离机制来解决。
(1)一种是加锁:读取数据之前对其加锁,防止其他事务对其修改
(2) 另一种是数据库的多版本控制(MVCC)
3 事务的四种隔离级别
为解决事务的并发问题,产生了四种不同级别的隔离机制。
- 读未提交 read uncommitted (脏读)
- 读已提交 read committed (不可重复读)
- 可重复读 repeatable read (幻读)
- 串行化 serializable
3.1 读未提交(脏读)
事务A和事务B,事务物A未提交的数据,事务B可以读取到。 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别。 三种并发问题都没解决。
set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
3.2 读已提交(不可重复度)
事务A只能读取到事务B提交的数据,这种级别可以避免“脏数据” ,这种隔离级别会导致“不可重复读取” ,Oracle默认隔离级别
set global transaction isolation level read committed;
查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
3.3 可重复读(幻读)
事务A和事务B,事务A提交之后的数据,事务B读取不到 - 事务B是可重复读取数据 - 这种隔离级别高于读已提交 - 换句话说,对方提交之后的数据,我还是读取不到 - 这种隔离级别可以避免“不可重复读取”,达到可重复读取 - 比如1点和2点读到数据是同一个 - MySQL默认级别 - 虽然可以达到可重复读取,但是会导致“幻像读”
set global transaction isolation level repeatable read;
查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
3.4 串行化
事务A和事务B,事务A在操作数据库时,事务B只能排队等待 这种隔离级别很少使用,吞吐量太低,用户体验差 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行, 而不并发
set global transaction isolation level serializable;
查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
Mysql默认的隔离级别是—可重复读,但是字啊InnoDB引擎中已经了幻读问题,具体是通过next-key-lock解决的,幻读本身是在事务A执行过程中事务B进行了新增或者删除操作,所以在Mysql的InnoDB引擎中引入了一种新的锁叫间隙锁(Gap锁),当事务A在执行时,如果仅仅通过行锁对数据加锁,那么事务B同样可以在两条数据之间插入新的数据,所以事务A只有将行之间的间隙也进行上锁,MySQL中将“行锁+间隙锁”叫做next-key-lock。