MySQL事务
事务
-
什么是事务
事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行
-
特点
一个事务中如果有一个数据库操作失败,那么整个事务的所有数据库操作都会失败,数据库数据就会回滚到该事务开始之前的状态。
-
限制
MySQL数据库中仅InnoDB和BDB类型的数据库表支持事务
事务的ACID原则(四大原则)
-
原子性(Atomic)
意味着数据库中的事务执行是作为原子粒度。即不可再分,整个语句要么执行,要么不执行
-
一致性(Consist)
即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
-
隔离性(Isolated)
事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据
-
持久性(Durable)
意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
MySQL实现事务的方法
-
SET AUTOCOMMIT
使用该语句来改变自动提交模式,等于0时关闭自动提交模式,等于1时开启自动提交模式。默认为1,使用事务时为0
-
START TRANSACTION
开始一个事务,标记事务的起始点
-
COMMIT
提交一个事务给数据库
-
ROLLBACK
将事务回滚,数据回到本次事务的初始状态
注意:COMMIT(提交)和ROLLBACK(回滚)只能选择其一
MySQL实现事务的步骤
-
关闭自动提交
set autocommit = 0;
-
开始事务
start transaction;
-
执行语句
转账案例,加入小牛给小铁转账10元,小牛的账户-10,小铁的账户+10,两个操作需要在同一个时间完成,即在一个事务中完成-- 模拟一个转账的流程 update bank set bmoney = bmoney-10 where bname = '小牛'; update bank set bmoney = bmoney+10 where bname = '小铁';
-
结束事务
-- a. commit; -- b. rollback;
-
开启自动提交
set autocommit = 1;
事务的隔离性
-
什么是事务的隔离性
为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离,事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行
-
实现事务的隔离性的方式
通常数据库里都是采用锁的机制,保证事务之间的隔离性。
MySQL中的锁
分类
- 基于锁的属性分类:共享锁(读锁、S锁),排他锁(写锁、X锁)
- 基于锁的粒度分类:表锁,行锁(记录锁,间隙锁,临建锁)
- 基于锁的状态分类:意向共享锁,意向排他锁
事务的隔离级别(重重重)
-
事务并发问题:
在事务并发执行的时候,如果不进行事务隔离,那么就会产生脏写、脏读、不可重复读、幻读的问题
-
脏写
一个事务修改了另外一个没提交的事务的值(没提交有可能回滚),而导致有可能数据前后不一致的问题
-
脏读
本质上,就是一个事务查询到了另个一个未提交的事务的值,而导致有可能数据前后不一致的问题
-
不可重复读
在避免脏读的前提下,可能出现不可重复读的情况
事务A查询数据且没提交事务,此时事务B修改了数据,事务A再查询一次查到的是事务B修改后的数据,事务C又修改了数据,事务A再查询一次查到的是事务C修改后的数据。事务A未提交事务,每次读到的数据可能都不一样,这种情况就是不可重复读
-
幻读
只出现在可重复读的情况,产生的原因是新增不加锁
事务A和事务B来对数据操作,先拿锁先操作,假如先拿到锁的事务B一直未提交事务,锁未释放,此时事务A对数据的操作就要一直等锁,为了提高一些效率,事务A会选择操作数据又不影响事务B的insert新增数据且不加锁,此时事务C查询数据会看到新增的数据,当事务A回滚时,刚刚新增的数据就没了,事务C看到的数据不同了,好像产生了幻觉就叫幻读。
一个事务执行过程中,由于其他事务的插入或删除操作,导致当前事务看到了这些操作产生的新数据,而之前的数据行仍然存在。这种现象在事务执行完成后无法保证一致性,因此被认为是幻读。
-
事务的隔离级别
级别 名称 1. READ_UNCOMMITTED 读未提交 2. READ_COMMITTED 读提交(不可重复读) 3. REPEATABLE_READ 可重复读 4. SERIALIZABLE 串行化
注意:每个隔离级别都针对事务并发问题中的一种或几种进行解决,事务级别越高,解决的并发事务问题也就越多,同时也意味着加的锁就越多,所以性能也会越差
- 事务隔离级别解决的问题