事务:一条或多条 sql 语句组成的一个执行单元,这组 sql 语句是一个整体,要么都顺利执行,要么都不执行,只要在执行的过程中,有一条 sql 语句执行错误就全部回滚或部分回滚。
事务总共有 4 大特性:ACID。
A(Atomicity)原子性
:一个事务是不可再分割的整体,要么都执行要么都不执行
C(Consistency)一致性
:一个事务可以使数据从一个一致状态切换到另外一个一致的状态。比如 A 和 B 的账户上都各有 1000 元,在 A 给 B 转了 500 元之后,A 的账户上 是 500 元,B 的账户上是 1500 元,两人的总额还是 2000 元。
I(Isolation)隔离性
:一个事务不受其他事务的干扰,多个事务互相隔离
D(Durability)持久性
:一个事务一旦提交了,则它对数据库中数据的改变就是永久性的
首先事务分为两类:一种是隐式事务,一种是显式事务。
像单条的 insert、update、delete 语句,本身都是一条事务,只不过由 MySQL 自动提交了。
而显式事务则需要我们自己手动的提交或回滚。
使用显式事务的步骤:
① 首先要开启事务,将自动提交关闭。
set autocommit = 0;
start transaction; #可以省略
② 编写一组 sql 语句,在其间可以设置会滚点。
savepoint 回滚点名; #设置回滚点`
③ 结束事务
提交:commit;
回滚:rollback;
回滚到指定的地方:rollback to 回滚点名;
演示 savepoint 的使用:
SET autocommit = 0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点
当多个事务同时操作同一个数据库的相同数据时,就会出现事务的并发问题。
那事务的并发问题都有哪些呢?
对于事务的并发问题,我们可以通过设置不同的隔离级别来解决这些并发问题。
MySQL 支持 4 种隔离级别:
隔离级别 | 描述 |
---|---|
READ UNCOMMITTED(读未提交数据) | 允许事务读取未被其他事务提交的变更脏读,不可重复读和幻读的问题都会出现 |
READ COMMITTED(读已提交数据) | 只允许事务读取已经被其它事务提交的变更。可以避免脏读,但不可重复读和幻读问题仍然可能出现 |
REPEATABLE READ(可重复读) | 确保事务可以多次从一个字段中读取相同的值。可以避免脏读和不可重复读,但幻读的问题仍然存在。 |
SERIALIZABLE(串行化) | 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入,更新和删除操作,所有并发问题都可以避免,但性能十分低下 |
隔离级别越高, 数据一致性就越好, 但并发性越弱。
补充:
Oracle 支持 2 种事务隔离级别:READ COMMITED 和 SERIALIZABLE。Oracle 默认的事务隔离级别为: READCOMMITED。
Mysql 默认的事务隔离级别为: REPEATABLE READ。
每启动一个 mysql 程序, 就会获得一个单独的数据库连接。每个数据库连接都有一个全局变量 @@tx_isolation, 表示当前的事务隔离级别。
查看当前的隔离级别: SELECT @@tx_isolation;
设置当前 MySQL 连接的隔离级别:set session transaction isolation level read committed;
设置数据库系统的全局的隔离级别:set global transaction isolation level read committed;
1、先创建一个表 account,往里面插入 2 条数据
CREATE TABLE `account` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`username` varchar(20) ,
`balance` int ,
);
INSERT INTO account(username,balance) VALUES('刘备',1000),('关羽',1000);
2、开启两个 MySQL 连接,首先设置数据库的隔离级别为:read uncommitted;
,演示出现的问题。
3、修改数据库的隔离级别为:read committed
,解决了脏读的问题,但是会出现不可重复读的问题。
4、修改数据库的隔离级别为:repeatable read
,解决了脏读和不可重复读的问题,但是会出现幻读。
5、修改数据库的隔离级别为:serializable
,脏读、不可重复读、幻读的问题都解决了。
最后,总结一下,不同的隔离级别都能解决什么问题:
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
READ UNCOMMITTED | × | × | × |
READ COMMITTED | √ | × | × |
REPEATABLE READ | √ | √ | × |
SERIALIZABLE | √ | √ | √ |