1.什么是事务
在实际的开发过程中,一个业务操作如:转账,往往是要多次访问数据库才能完成的。转账是一个用户扣钱,另一个用户加钱。如果其中有一条 SQL 语句出现异常,这条 SQL 就可能执行失败。
事务执行是一个整体,所有的 SQL 语句都必须执行成功。如果其中有 1 条 SQL 语句出现异常,则所有的
SQL 语句都要回滚,整个业务执行失败
#创建账户表
CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), balance DOUBLE ); INSERT INTO account (NAME, balance) VALUES ('zs', 1000), ('ls', 1000);
#手动提交事务模拟张三给李四转 500 元钱,一个转账的业务操作最少要执行下面的 2 条语句:张三账号-500李四账号+500
-- 开启事务 START TRANSACTION; -- 张三账号-500 UPDATE account SET balance = balance - 500 WHERE NAME='zs'; -- 李四账号+500 问题1 UPDATE account SET balance = balance + 500 WHERE NAME='ls'; -- 回滚事务 ROLLBACK;
-- 开启事务 START TRANSACTION; -- 张三账号-500 UPDATE account SET balance = balance - 500 WHERE NAME='zs'; -- 李四账号+500 -- 问题1 UPDATE account SET balance = balance + 500 WHERE NAME='ls'; -- 提交事务 没有问题,则提交事务 COMMIT; -- 回滚事务 发现出问题才回滚 ROLLBACK;
事务提交的两种方式:
手动提交:需要先开启事务,再commit
自动提交:mysql是自动提交的,通过set @@autocommit = 0,来手动提交。@@表示全局变量,1 表示开启,0 表示关闭
2.事务的四大特性ACID
1.原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
2.持久性: 当事务一旦提交或回滚,数据会发生持久化的保存。
3.隔离性:多个事务之间相互独立。
4.一致性:数据在操作前后,总量不变。
3.事务的隔离级别
存在问题:
1)脏读:一个事务,读取到另一个事务没有提交的数据。
2)不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
3)幻读:一个事务的操作(DML)数据表中的所有记录,另一个事物添加了一条数据,则第一个事务查询不到自己的修改
隔离级别会出现的问题:
1) read uncommitted:读未提交
脏读,不可重复读,幻读
2)read commited:读已提交(oracle或SQL Server默认)
不可重复读,幻读
3)repeatable read:可重复读(mysql默认)
幻读
4)serializable:串行化
安全性依次提高,但效率降低。
设置隔离级别:
set global transaction isolation level read committed;