事务就是一组dml语句组成,这些语句在逻辑上存在相关性,这一组dml语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据时不相同的。
事务理论的深度理解参见推荐书籍:《数据库系统概念》的第14章。
银行转账的例子更需要考虑事务的问题。
create table account(
id int primary key,
name varchar(50) not null default '',
balance decimal(10, 2) not null default 0.0
);
基本使用:
开始一个事务
start transaction;
做一个保存点
savepoint 保存点名;
进行各种操作
如果需要,可以回到保存点
rollback to 保存点名;
示例:
mysql> start transaction; --开启事务
Query OK, 0 rows affected (0.00 sec)
mysql> savepoint aa; --设置保存点aa
mysql> insert into account values(1, '张三', 10); --添加一条记录
Query OK, 1 row affected (0.00 sec)
mysql> savepoint bb; -- 设置保存点bb
Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values(2, '李四', 10000); --再添加一条记录
Query OK, 1 row affected (0.00 sec)
mysql> select * from account; --两条记录都在了
mysql> rollback to bb; -- 发现后来添加这一条记录是误操作。所以回滚到bb状态
Query OK, 0 rows affected (0.01 sec)
mysql> select * from account; -- 第二条记录没有了
事务操作注意点:
如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是还没有提交)
mysql> start transaction; -- 开启事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values(1, 'zzz',200); -- 插入数据
Query OK, 1 row affected (0.00 sec)
mysql> select * from account; -- 已经存在
ysql> rollback; -- 回滚到事务开始
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; -- 表中没有数据了
Empty set (0.00 sec)
如果一个事务被提交了,则不可以回退(commit)
如果一个事务被提交了,则不可以回退(commit)
mysql> start transaction; -- 开启事务
mysql> insert into account values(1, 'aa', 1000); --插入两条数据
mysql> commit; -- 提交
mysql> rollback; -- 回滚
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; -- 数据依然存在
可以选择回退到哪个保存点
InnoDB支持事务,MyISAM不支持事务
开始事务可以使 start transaction 也可以是 set autocommit = 0
事务的隔离级别
当我们有多个客户端同时操作数据库的某张表,如何进行隔离操作?MySQL提供了隔离级别。
当MySQL表被多个线程或者客户端开启各自事务操作数据库中的数据时,MySQL提供了一种机制,可以让不同的事务在操作数据时,具有隔离性。从而保证数据的一致性。
如果不考虑隔离性,可能会引发一下问题:
脏读
不可重复读
幻读
事务的隔离级别有几种:
如何设置事务的隔离级别
语法:
set session transaction isolation level read uncommitted;
查看当前的隔离级别:
mysql> select @@tx_isolation;
脏读:一个客户端(事务)会读取到另外一个客户端(事务)没有提交的修改数据。
不可重复读:同一个查询在同一个事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生不可重复读。
幻读:同一个查询在同一个事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发
生幻读。
可串行化,如下图所示:
当客户端A在执行select过程中,DBMS会对库加锁,如果这时客户端B执行插入,只要还没释放锁,插入不进去,会将B的update语句放入等待队列,直到释放了锁或超时。
示例:
说明:
mysql默认的隔离级别是可重复读,一般情况下不要修改
事务的ACID特性
1. 原子性(Atomicity):
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2. 一致性(Consistency):
事务必须使数据库从一个一致性状态变到另外一个一致性状态。
3. 隔离性(Isolation):
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
4. 持久性(Durability):
持久性是指一个事务一旦被提交,它对数据库中的数据的修改就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
—知识未完,待看下篇!!!