一、事务的基本要素(ACID)

1、原子性(Atomicity)

事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

2、一致性(Consistency)

事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

3、隔离性(Isolation)

同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

4、持久性(Durability)

事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

二、事务隔离级别的查看和修改

事务隔离级别的查看:
mysql8之前:

select @@GLOBAL.tx_isolation;
select @@tx_isolation;

mysql8之后

select @@GLOBAL.transaction_isolation;
select @@transaction_isolation;

事务隔离级别的修改

set session transaction isolation level repeatable read;
set session transaction isolation level serializable;
set session transaction isolation level read committed;
set session transaction isolation level read uncommitted;

三、事务的四种隔离级别

1、Serializable 串行化

事务之间的执行是一个执行完另一个再执行,每次只执行一个

2、repeatable-read 可重复读

Mysql的默认事务隔离级别
一个正在执行的事务的变化,不能被其他事务所看见

例如一个真在执行的事务A:

START TRANSACTION;
SELECT grade from user WHERE username='zhangsan';
SELECT grade from user WHERE username='zhangsan';
COMMIT;

执行到第一句查询sql时,zhangsan的grade=10,
这时另一个事务B修改了zhangsan的grade并提交

start transaction;
update user set grade=30 where username='zhangsan';
commit;

此时事务A执行第二句查询sql,zhangsan的grade也为10,并未改变

可重复读会出现幻读的问题:
给username增加unique约束
当事务A刚开启:

START TRANSACTION;
SELECT grade from user WHERE username='wangwu';
insert into user(grade,username) values (15,'wangwu');
COMMIT;

此时事务B执行并提交,插入数据wangwu:

start transaction;
insert into user(grade,username) values (15,'wangwu');
commit;

再继续执行事务A,此时事务A既查询不到wangwu的数据,也无法插入wangwu的数据,出现幻读

3.read-committed读已提交

处于不可重复读级别的事务,可以看到其他已经提交的事务对数据的修改。也就是说,如果其他事务修改了相应的表,那么同一个事务中多个sql语句查询同一条数据可能返回不同的结果

也会出现幻读的问题
例子和上面相同

4.read-uncommitted读未提交

处于读未提交隔离级别的事务,可以读到其他事务执行但未提交的数据,会产生脏读和幻读
幻读:
事务A开启:

start transaction;
select * from user where username='zhaoliu';
delete from user where username='zhaoliu';
commit;

此时事务B开启并执行插入zhaoliu的语句但未提交

START TRANSACTION;
insert into user(grade,username) values (15,'zhaoliu');
COMMIT;

此时事务A执行查询zhaoliu和删除zhaoliu的语句,可以查询到,但是不能删除,因为事务B还未提交,这就会出现幻读

脏读:
一个事务可以查看到您一个事务还未提交的数据,但一但另一个事务发生回滚,这个事务就会出错.

4、原理(MVCC)

先看MVCC简单理解 再看MVCC具体剖析MVCC如何实现数据库读已提交和可重复读这两种隔离级别?