什么是事务
事务的英文是transaction,而transaction还有交易
的意思。事务就是一连串操作( 比如增删改 )的集合。事务内的操作要么全部成功,要么全部失败,如果某一步操作失败,那么这个事务内之前的操作都要回滚。
事务应该具备原子性 (Atomicity)、一致性 (Consistency)、隔离性 (Isolation)、持久性 (Durability)这四个特性,简称acid
。
acid
-
原子性:一个事务就是一个完整单元,要么全部成功,要么全部失败。
-
一致性:事务从开始要结束的任何时刻,数据都是一致的。
-
隔离性:事务之间是相互独立的,中间状态的数据互不可见。
-
持久性:数据的修改应该是永久的。
事务的问题
多个事务并发对相同的数据进行操作时,就会出现一系列违反了事务四特性的问题,可总结成以下3个:
-
脏读
读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。
这违背了事务的隔离性。 -
不可重复读
在同一事务内,不同的时刻读到的同一批数据可能是不一样的。
比如:别的事务执行了update操作,并提交了事务。 这违背了事务的一致性。 -
幻读
A事务在本次事务中,先读取了一遍数据,发现数据不存在,过了一会,又读取了一遍,发现又有数据了。(破坏了一致性,重点是insert)
事务的隔离级别
为了解决上述的问题,ISO制定了事务隔离级别的标准。
- 未提交读(read-uncommitted):最低级别,基本只保证持久性;会出现脏读,不可重复读,幻读的问题。
- 已提交读(read-committed):语句级别;会出现不可重复读,幻读的问题。
- 可重复读(repeatable-read):事务级别;只会出现幻读问题。
- 串行化(serializable):最高级别,也就是事务与事务完全串行化执行,无并发可言,性能低;但不会出现任何问题。
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 会 | 会 | 会 |
不可重复读(read-committed) | - | 会 | 会 |
可重复读(repeatable-read) | - | - | 会 |
串行化(serializable) | - | - | - |
注意:这四个级别只是一个标准,各个数据库厂商,并不完全按照标准做的
实操
查看事务级别
MySQL的Innodb
引擎默认的隔离级别:REPEATABLE-READ
# 查看事务隔离级别 5.7.20 之后
show variables like 'transaction_isolation';
SELECT @@transaction_isolation
# 5.7.20 之前
SELECT @@tx_isolation
show variables like 'tx_isolation'
修改事务隔离级别
set [作用域] transaction isolation level [事务隔离级别]
- 作用域:session | global
- 事务隔离级别:READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
进行事务操作
begin 命令并不代表事务的开始,事务开始于 begin 命令之后的第一条语句执行的时候。例如下面示例中,select * from xxx 才是事务的开始,
begin;
select * from xxx;
commit; -- 或者 rollback;