MySQL事务定义
事务是一个最小的不可再分的单元,通常一个事务对应一个完整的业务,多个操作同时进行,要么同时成功,要么同时失败,这就是事务。
例如:银行账户转账业务,该业务是一个最小的工作单元,该业务需要批量的DML(insert、update、delete)语句共同联合完成。
MySQL事务特征
MySQL事务具有四大特征,简称ACID:
1.原子性(Atomicity)
所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。
2.一致性(Correspondence)
数据必须保证从一种一致性的状态转换为另一种一致性状态。
3.隔离性(Isolation)
指当多个用户并发操作数据库时,数据库为每一个用户开启不同的事务,这些事务之间相互不干扰,相互隔离。
4.持久性(Durability)
事务一旦commit,则数据就会保存下来,即使提交完之后系统崩溃,数据也不会丢失。
一般来说,事务是必须满足4个条件(ACID)。
MySQL事务用法
MySQL事务有两种方式,分别为 显式事务 和 隐式事务 。
1.显式事务
开启事务,先执行begin,结束事务,成功执行commit,失败执行rollback。
# 开启事务 mysql> BEGIN; # 提交事务。当提交事务后,对数据库的修改是永久性的。 mysql> COMMIT; # 回滚事务。即撤销正在进行的所有没有提交的修改 mysql> ROLLBACK; # 将事务回滚到某个保存点。 mysql> ROLLBACK TO [SAVEPOINT]
示例:
mysql> use mikechen; # 创建数据表 mysql> CREATE TABLE user_id( id int(5)) engine=innodb; mysql> select * from user_id; # 开始事务 mysql> begin; mysql> insert into user_id value(1); mysql> insert into user_id value(2); mysql> insert into user_id value(3); # 提交事务 mysql> commit;
2.隐式事务
mysql默认开启了自动提交,在执行insert,update,delete语句时候每一条sql语句就是一个事务。
MySQL中有一个系统变量 autocommit,如下所示:
mysql> SHOW VARIABLES LIKE 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 1 row in set (0.01 sec)
当我们设置 autocommit=1 时,每条 SQL 语句都会自动进行提交,设置 autocommit=0 时都需要用 COMMIT 进行提交,让事务生效。
设置如下:
# 查看自动提交 show global variables like 'autocommit'; 关闭自动提交: set global autocommit=0; 开启: set global autocommit=1;
MySQL事务原理
MySQL架构,如下图所示:
每次update、insert、delete类型的SQL执行时都会先写三条日志。
- bin log记录执行的每条SQL,用来做主从复制;
- redo log记录修改内容和修改页的位置,用来维护持久性;
- undo log记录相反类型的SQL,用来做rollback和实现mvcc。
MySQL innoDB引擎中数据的一致性和原子性一样,也是用事务日志undo log实现的。
- 事务的原子性是通过undo log(回滚日志)实现的;
- 事务的持久性是通过redo log 来实现的;
- 事务的隔离性是通过(读写锁+MVCC)来实现的;
事务的一致性是通过原子性,持久性,隔离性来实现的。
MySQL事务的隔离级别
MySQL事务隔离级别主要是四种:读未提交、读已提交、可重复读、串行化。
1. read uncommitted(读未提交)
读未提交:允许事务读取未被其他事务提交的变更。
【会产生的问题】:脏读、不可重复读、幻读
2. read committed(读已提交)
读已提交:只允许事务读取已经被其他事务提交的变更。
【会产生的问题】:不可重复读、幻读。
3.repeatable read(可重复读)
可重复读:确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新(update)。
【会产生的问题】:幻读。
幻读:指一个事务执行多次查询,但是多次查询的数据的结果中包含了第一不存在的数据或数据有减少。
4. serializable(串行化)
串行化:一般不会使用,它会给每一 行读取的数据加锁,造成大量的等待和锁冲突。
【会产生的问题】:可以解决所有问题。
mikechen睿哥
mikechen睿哥,十余年BAT架构经验,资深技术专家,就职于阿里、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》