mysql事务使用&原理
1.什么事务
事务是一个整体,由一条或者多条sql语句组成,这些sql语句要么都执行成功,要么都执行失败,只要有一条sql语句出现异常,整个操作就会回滚,整个业务就会执行失败。
回滚:当事务运行中出现异常不能执行时,系统将事务中对数据库的所有已完成的操作全部撤销,回到事务开始时的状态。
2.事务使用
2.1手动提交事务
功能 | 语句 |
---|---|
开始事务 | start transaction;或者begin; |
提交事务 | commit |
回滚事务 | rollback |
流程:
成功:开启事务>执行多条sql语句>成功提交
失败:开启事务>执行多条sql语句>事务的回滚
2.2自动提交事务
mysql默认每一条DML(增删改)语句都是一个单独的事务(mysql默认是自动提交事务)
2.3关于事务操作
查看autocommit状态
show variables like 'autocommit';
设置autocommit状态(on为自动提交,off为手动提交)
set @@autocommit=off;
3.事务的四大特性ACID
原子性(Atomicity)、一致性( Consistency)、隔离性( Isolation )和持久性( Durability)
特性 | 含义 |
---|---|
原子性 | 每个事务都是一个整体,不可拆分,事务所有的sql语句要么都执行成功,要么都失败 |
一致性 | 事务在执行前数据库的状态与执行后数据库的状态保持一致 |
隔离性 | 事务与事务之间不应该相互影响,并发执行时保持隔离状态 |
持久性 | 一旦事务执行成功,对数据库的修改是持久的 |
实现原理
**原子性:**undo log
实现原子性的关键,是当事务回滚时能够撤销所有已经执行成功的SQL语句,InnoDB实现回滚,靠的是undo log,当事务对数据库进行修改时,InnoDB会生成对应的;如果事务执行失败或者调用了rollback,导致事务需要回滚,就利用undo log中的信息将数据回滚到修改之前的样子
一致性:
原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。
隔离性:
InnoDB默认的隔离级别是RR(可重复读),RR的实现主要基于锁机制。锁机制的基本原理可以概括为事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。(共享锁和独占锁)
最简单的读操作和写操作
- (一个事务)的写操作对(另一个事务)写操作的影响:锁机制保证隔离性
- (一个事务)的写操作对(另一个事务)读操作的影响: MVCC保证隔离性
持久性:
基于redo logo,redo log就被引入来解决这个问题(宕机导致BP中的数据没有刷新磁盘,造成数据丢失),当数据被修改时,除了修改BP中的数据,还会在redo log中记录这次操作,当事务提交时,会调用fsync接口对 redo log进行刷盘,如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复,redo log采用的是WAL(Write-ahead logging,预写式日志), 所有修改先写入日志,在更新到BP,保证了数据不会因为MySQL宕机而丢失,从而满足了持久性的要求。
4.隔离级别
并发操作时,当多个用户同时访问同一个数据时可能引发并发问题
问题 | 说明 |
---|---|
脏读 | 一个事务读取到了另一个事务的中尚未提交的数据 |
不可重复读 | 一个事务两次读取到的数据内容不一致,要求的是一个事务中多次读取时的数据是一致的,这是进行update操作时引发的问题 |
幻读 | 一个事务中,某个select相同操作的多次查询结果不一致数据不准确,无法支持后续的业务操作 |
可以通过设置隔离级别防止上面三种并发问题
名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|
读未提交 | read uncommitted | √ | √ | √ |
读已提交 | read committed | × | √ | √ |
可重复读 | repeatable read | × | × | √ |
串行化 | serializable | × | × | × |
设置隔离级别相关sql语句
#查看隔离级别
select @@tx_isolation;
#设置隔离级别
set global transaction isolation level 填隔离级别;
设置后退出再进入mysql才能生效