事务由一组DML(数据操纵语言)语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败
1.事务的基本操作
- 开始一个事务
start transaction
- 创建一个保存点
savepoint 保存点名;
- 回到保存点
rollback to 保存点名;
演示:
–创建一张表
mysql> create table account(
-> id int primary key,
-> name varchar(50) not null default '',
-> balance decimal(10,2) not null default 0.0);
Query OK, 0 rows affected (2.42 sec)
–开始事务
mysql> start transaction;
Query OK, 0 rows affected (0.05 sec)
–设置保存点a
mysql> savepoint a;
Query OK, 0 rows affected (0.05 sec)
–插入一条数据
mysql> insert into account values(1,'张三',10);
Query OK, 1 row affected (0.28 sec)
–设置保存点b
mysql> savepoint b;
Query OK, 0 rows affected (0.00 sec)
–插入一条数据
mysql> insert into account values(2,'李四',1000);
Query OK, 1 row affected (0.00 sec)
查看表中数据,发现两条数据都在
mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | 张三 | 10.00 |
| 2 | 李四 | 1000.00 |
+----+------+---------+
2 rows in set (0.16 sec)
–发现添加一条记录是误操作,回滚到b状态
mysql> rollback to b;
Query OK, 0 rows affected (0.06 sec)
查表,发现–第二条记录没有了
mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | 张三 | 10.00 |
+----+------+---------+
1 row in set (0.00 sec)
2.事务的注意事项
- 若没有设置保存点,也可以回滚,只能回滚到事务的开始,直接使用rollback(前提是事务还没有提交)
- 若一个事务被commit,则不可以rollback
- 若设置保存点,可以选择rollback到那个保存点
- InnoDB支持事务,MyISAM不支持事务
- 开始事务:start transaction
3.事务的隔离级别
3.1不考虑隔离,会发生以下问题
-
脏读
指一个事务读到了另一个事务未提交的数据
案例:
1.财务把小明的工资100修改为200,但没有提交
2.小明读到自己自己工资变为200,开心~~
3.财务发现操作失误,应该给小丽加工资的,回滚了事务,小明的工资又变为100
这样小明读取的200就是一个脏数据 -
不可重复读()
指的是在一个事务中,两次查询到的结果不一致(针对update)
案例:
1.在事务1中,小明读取到自己的工资为100
2.在事务2中,财务修改了小明的工资为200,并提交了事务
3.在十五1中,小明再次读到自己的工资200 -
幻读
指的是,在一个事务中,两次查询到的结果不一致(针对insert或者delete)
案例:
现在工资为100的员工有10人
1.事务1读取所有工资为100的人,有10条记录
2.事务2,向员工表中又insert了一组值,该员工的工资也为100
3.事务1再次读取所有工资为100的人,产生11条记录
3.2事务的隔离级别
- 读未提交 (Read uncommitted):最低级别,以上问题都不能避免
- 读以提交(Read committed):可避免脏读发生,Oracle默认隔离级别
- 可重复读(Reptable read):可避免脏读、不可重复读,MySQL默认隔离级别
- 串行化(Serializable):可避免脏读、不可重复读、幻读
串行化案例:当客户端A执行select过程中,DBMS(数据库管理系统)会对库加锁,若客户端B执行insert/update/delete操作时,就会将这些操作放入等待队列,直到释放锁或超时
3.3设置事务的隔离级别
语法:
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.15 sec)
3.4查看当前的隔离级别
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.07 sec)
4.事务的ACID特性
- 原子性(Atomicity):
事务是应用中最小的执行单位,原子性指的是事务锁包含的所有操作要么全部成功,要么全部失败 - 一致性(Consistency):
一致性指的是一个事务在执行前和执行后都必须处于一致性状态(A和B一共有200块钱,不管是A给B,还是B给A,他俩的钱加起来还是200) - 隔离性(Isolation):
各个事务之间互不干扰,任何一个事务的内部操作对其他事务都是不可见的 - 持久性(Durability):
持久性指的是一个事务一旦被提交,那么对数据库中数据的改变都是永久性的