事务是程序中一系列严密的操作,所有的操作必须完成,否则在所有的操作中所做的所有的更改都会被撤销。也就是事务的原子性,一个事务中的一系列的操作要么全部成功,要么就是失败。
事务的结束有两种,当事务中所有的步骤全部成功执行的时候,事务提交。如果其中一个步骤失败,将会发生回滚操作,撤销到事务开始之前的所有的操作。
事务具有四个特征
原子性 事务是数据库的逻辑工作单位,事务中包含多个操作,要么都做完,要么都不做 隔离性(隔离性也是本文的重点) 事务彼此之间是不能互相干扰的,即一个事务的操作对该数据库的其他事务操作是隔离的,并发执行的各个事务时间互补干扰 持久性 事务一旦提交,其变更是性的 一致性 事务执行的结果必须满足从一个状态变到另一个状态,因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性的状态。如果数据库系统在运行时发生系统故障,有些未完成的事务被迫中止,而有一部分修改已经写入数据库,这个时候数据库就处于一种不正确的状态。
读取未提交的数据【Read Uncommitted】 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的) 读取提交的内容【Read Committed】 该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别也支持不可重复读,即同一个 select 可能得到不同的结果 可重读【Repeatable Read】 这是 MySQL 默认的隔离级别,它确保同一个事务在并发读取数据时,会看到同样的数据行。不过理论上会导致另外一个问题,【幻读】。幻读:相同的条件查询一些数据,然后其他事务【新增】或者是【删除】了该条件的数据,然后导致读取的结果不一样多。InnoDB 存储引擎通过多版本控制(MVCC)机制解决了该问题 可串行化【serializable】 这是事务的高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)
脏读 读取了前一个事务未提交的或者是回滚的数据 不可重复度 同样的 select 查询,但是结果不同,过程中有事务更新了原有的数据 幻读 两次查询的结果数量不一样,过程中有事务新增或者是删除数据
show variables like '%isolation%'
set session transaction isolation level Read Uncommitted;
Read Uncommitted
实验一:Read Uncommitted
Read Uncommitted
即:读取未提交set session transaction isolation level Read Uncommitted;
start tracsaction;
select * from test;
start transaction;
select * from test;
update test set num =10 where id = 1
;B没有提交事务rollback;
select * from test;
select * from test;
实验二:读取已提交-Read Committed
Read Committed;
set session transaction isolaction level Read Committed;
start transaction;
select *from test;
start transaction;
select * from test;
update test set num =10 where id=1
select * from test;
commit;
select * from test;
Read Committed
读已提交的隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务A在两次查询的结果不一致,因为在两次查询之间事务B更新了一条数据。实验三:可重读度-Repeatable Read
set session transaction isolation level repeatable read;
start transaction;
select * from test;
start transaction;
select * from test;
update test set num=10 where id=1;
select * from test;
commit;
select * from test;
此时A查询的记录仍然和之前一样inset into test(num) value(4);
select * from test;
Repeatable Read
隔离级别只允许读取已经提交的事务的记录,实验四:串行化-Serializable
serializable
完全锁定字段,若一个事务来操作同一份数据,那么就必须等待,直到前一个事务完成并解除锁为止。是完整的隔离级别,会锁住对应的数据表,因为会导致效率问题。