本文共 2497 字,大约阅读时间需要 8 分钟。
事务是一个整体,由一条或多条SQL语句组成,这些SQL语句要么都执行成功,要么都执行失败。只要有一条SQL出现异常,整个操作就会回滚,整个业务执行失败。
例如:银行的转账业务,Kobe给Curry转账500元,至少要操作两次数据库,Kobe-500,Curry+500。这中间任何一步出现问题,整个操作必须全部回滚,这样才能保证用户和银行都没有损失。
CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), money DOUBLE);SELECT * FROM account;INSERT INTO account(NAME, money) VALUES('kobe', 1000), ('curry', 1000);
-- 给Kobe-500UPDATE account SET money = money - 500 WHERE name = 'kobe';-- 给Curry+500UPDATE account SET money = money + 500 WHERE name = 'curry';
事务回滚是指在事务运行过程中发生某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销,滚回到事务开始时的状态(在提交之前执行)。
在MySQL中,可以有两种方式进行事务的操作:手动提交事务和自动提交事务。
功能 | 语句 |
---|---|
开启事务 | START TRANSACTION |
提交事务 | COMMIT |
回滚事务 | ROLLBACK |
成功提交事务流程:
失败提交事务流程:
USE db_mysql;
START TRANSACTION;
-- 给Kobe-500UPDATE account SET money = money - 500 WHERE name = 'kobe';-- 给Curry+500UPDATE account SET money = money + 500 WHERE name = 'curry';
COMMIT;
MySQL默认每一条DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,语句执行完毕后自动提交事务。
MySQL默认是自动提交事务,可以设置为手动提交。
SHOW VARIABLES LIKE 'autocommit';
SET @@autocommit=off;
特性 | 含义 |
---|---|
原子性 | 每个事务都是一个整体,所有SQL语句要么都成功,要么都失败。 |
一致性 | 事务执行前后数据库状态保持一致。 |
隔离性 | 事务与事务之间保持隔离,不互相影响。 |
持久性 | 事务执行成功后,数据库修改持久有效。 |
一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库。数据库的相同数据可能被多个事务同时访问,如果不采取隔离措施,会导致各种问题,破坏数据的完整性。
问题 | 含义 |
---|---|
脏读 | 一个事务读取到了另一个事务中尚未提交的数据。 |
不可重复读 | 一个事务中两次读取的数据内容不一致。 |
幻读 | 一个事务中某一次的SELECT操作得到的数据状态无法支撑后续业务操作。 |
级别 | 常见操作 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|
1 | 读未提交 | 是 | 是 | 是 | |
2 | 读已提交 | 否 | 是 | 是 | Oracle、SQLServer |
3 | 可重复读 | 否 | 否 | 是 | MySQL |
4 | 串行化(可串行化) | 否 | 否 | 否 |
SELECT @@tx_isolation;
SET global transaction isolation level {read uncommitted, read committed, repeatable read, serializable};
脏读是指一个事务读取到了另一个事务中尚未提交的数据。
将全局隔离级别设置为read committed
。
SET global transaction isolation level read committed;
不可重复读是指一个事务中两次读取的数据内容不一致。
将全局隔离级别设置为repeatable read
。
SET global transaction isolation level repeatable read;
幻读是指一个事务中某一次的SELECT操作得到的数据状态无法支撑后续业务操作。
将事务隔离级别设置为serializable
。
SET global transaction isolation level serializable;
通过合理设置隔离级别,可以有效防止并发访问引起的脏读、不可重复读和幻读问题。不过,serializable
隔离级别会导致事务只能排队执行,严重影响数据库性能,数据库通常不会使用这种隔离级别。
转载地址:http://rcp.baihongyu.com/