事务的实现机制与实际应用:
- 事务概述
- 事务控制语句
- 事务隔离级别
- InnoDB锁机制
- 事务概述
事务特性:
- 原子性(Atomicity): 事务中所有的操作视为一个原子单元,即对事务所进行的数据修改等操作只能是完全提交或者完全回滚。
- 一致性(Consistency): 事务在完成时,必须使所有的数据从一种一致性状态变更为另外一种一致性状态,所有的变更都必须应用于事务的修改,以确保数据的完整性。
- 隔离性(Isolation):一个事务中的操作语句所做的修改必须与其他事务所做的修改相隔离。在进行事务查看数据时,数据所处的状态,要么是被另一并发事务修改之前的状态,要么是被另一并发事务修改之后的状态,即当前事务不会查看由另一个并发事务正在修改的数据。这种特性通过锁机制实现。
- 持久性(Durability): 事务完成之后,所做的修改对数据的影响是永久的,即使系统重启或者出现系统故障数据仍可以恢复。
(1) REDO日志
事务执行时需要将执行的事务日志写入到日志文件里,对应的文件为REDO日志。日志缓冲区的刷新方法或者时间间隔可以通过参数innodb_flush_log_at_trx_commit控制。
REDO日志对应磁盘上的ib_logfileN文件,该文件默认为5MB,建议设置为512MB以便容纳较大的事务。其中ib_logfile0和ib_logfile1为REDO日志。
(2) UNDO日志
与REDO日志相反,UNDO日志主要用于事务异常时的数据回滚,具体内容就是复制事务前的数据库内容到UNDO缓冲区,然后在合适的时间将内容刷新到磁盘。
- 事务控制语句
# 查看MySQL隔离级别
show variables like 'tx_isolation';
# 创建测试需要的表,注意存储引擎为InnoDB
use test
# 创建表
create table test_1(
id int,
username varchar(20)
)engine=InnoDB;
# 插入语句
insert into test_1
values(1,'petter'),
(2,'bob'),(3,'allen'),(4,'aron');
# 查询数据
select * from test_1;
# 开启一个事务
begin;
# 更新一条记录
update test_1 set username='test' where id=1;
OK, 1 row affected (0.00 sec)
# 提交事务
commit;
# 查询数据
select * from test_1;
# 开启另一个事务
begin;
# 更新数据
update test_1 set username='petter' where id=1;
# 查询数据
select*from test_1;
# 回滚事务
rollback;
# 查询数据
select * from test_1;
- 事务隔离级别
# 未提交读
set global transaction isolation level read uncommitted;
# 提交读
set global transaction isolation level read committed;
# 可重复读
set global transaction isolation level repeatable read;
# 可串行读
set global transaction isolation level serializable;
(1)READ-UNCOMMITTED(读取未提交内容)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。读取未提交的数据被称为脏读(Dirty Read);
(2)READ-COMMITTED(读取提交内容)
这是大多数数据库系统的默认隔离级别,但不是MYSQL的默认隔离级别。满足了隔离的简单定义: 一个事务从开始到提交前所做的任何改变都是不可见的,事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理期间可能会有新的数据提交导致数据改变,所以同一查询可能返回不同结果,此级别导致不可重复读。
(3)REPEATABLE-READ(可重读)
这是MYSQL默认的事务隔离级别,能确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。理论上会导致幻读(Phantom Read)。
(4) Serializable(可串行化)
这是最高的隔离级别,通过强制事务排序,是之不可能相互冲突,从而解决幻读问题。简言之,就是在每个读的数据行上加上共享锁实现。这个级别,可能会导致大量的超时现象和所竞争,一般不推荐使用。
- InnoDB锁机制
(1) 锁的类型(共享锁/排他锁/意向锁)
- 共享锁
共享锁代号是S,是Share的缩写,共享锁的所力度是行或者元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围内的数据执行读操作。 - 排他锁
排他锁的代号是X,是eXclusive的缩写,排他锁的粒度与共享锁相同,也是行或者元组。一个事务获取了排他锁之后,可以对锁定范围内的数据执行写操作。 - 意向锁
意向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁(IS)和意向排他锁(IX)两类。意向共享锁表示一个事务有意对数据上共享锁或者排他锁。“有意”表示事务想执行操作但还没有真正执行。
(2) 锁粒度
锁的粒度主要分为表锁和行锁。
表锁管理锁的开销最小,同时允许的并发量也是最小的锁机制。行锁可以支持最大的并发。