概述
通俗来讲事务就是多步操作要么全部成功要么全部失败,保证最终状态一致。 为了简化应用程序,使其可以忽略一些潜在错误和并发问题,数据库层对事务的ACID特性做了统一支持。
事务的基本特性
事务有四大特性:原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability),俗称:ACID
-
原子性(Atomicity)
要么一起成功,要么一起失败 -
一致性(Consistency)
事务前后的数据完整性要保证一致 -
持久性(Durability)
事务一旦提交则不可逆,持久化到数据库中 -
隔离性(Isolation)
事务的隔离性是多用户并发访问数据库时,数据库为每一个用户开始的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要有隔离性- 脏读
指一个事务读取了另外一个事务未提交的数据 - 不可重复读
在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误的,只是某次场合不对)针对update操作 - 虚读(幻读)
是指在一个事务内读到了别的事务插入的数据,导致前后读取不一致 针对inset和delete操作
- 脏读
事务的基本操作
-- mysql 是默认开启事务自动提交的
set autocommit = FALSE -- 关闭 指事务非自动提交
set autocommit = TRUE -- 默认开启
savepoint [保存点名] -- 设置一个事务的保存点
rollback -- 全部回滚
rollback to savepoint [保存点名] -- 回滚到保存点
commit -- 提交事物,所有的操作
release savepoint [保存点名] -- 撤销一个保存点
start transaction; -- 开启事物
select @@transaction_isolation; --查看隔离级别
-- 设置当前 MySQL 连接的隔离级别
set session transaction isolation level read committed;
-- 设置数据库系统的全局的隔离级别
set global transaction isolation level [read uncommitted | read committed | repeatable read | serializable];
select * from account;
update account set uname = 'tom' where id = 100;
update account set money = 1300 where id = 100;
update account set money = 1600 where id = 100;
insert into account values(200,'lala',2000);
显示事务
START TRANSACTION 或者 BEGIN,作用是显示开启一个事务
START TRANSACTION 后面可以追加 修饰符
READ ONLY标识当前事务是一个只读事务,也就是属于该事务的数据库操作只能读取数据,而不能修改数据
补充:只读事务中只是不允许修改哪些其他事物也能访问到的表中的数据,对于临时表来说(我们使用 CREATE TEMPORARY TABLE 创建的表),由于它们只能在当前会话中可见,所以只读事物其实也是可以对临时表进行增、删、改操作的
READ WRITE(默认)WITH CONSISTENT SHAPSHOT启动一致性
事务隔离级别
它们分别会对应一些并发问题,如表格所示:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
|---|---|---|---|---|
| 读未提交(read uncommitted) | ||||
| 读已提交(read committed) | ||||
| 可重复读(repeatable read) | ||||
| 可串行化(serializable) |
注意:可重复读(repeatable read) 模式幻读出现在,更新了一个其他事务插入的值时才会出现
mysql1开启事务,执行 update account set uname = 'tom' where id = 100;
此时mysql2也开启事务,并查询数据库数据,此时数据未改变,然后执行update account set money = 1300 where id = 100; 发现进程等待
mysql1 执行commit; 查看数据
当 mysql1 执行commit;完后mysql2进程等待解除 更新完成了 update account set money = 1300 where id = 100;的操作,此时 mysql2还未commit;,但是 uname 执已近更新,所以出现幻读
最终数据如下