一、事务简介。
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
mysql数据库的事务默认自动提交,也就是说当执行一条sql语句,mysql会立即隐式的提交事务。
示例:银行转账。
开始事务 | ||
查询张三账户余额 | ||
张三账户余额-1000 | 抛异常 | 回滚事务 |
李四账户余额+1000 | ||
提交事务 |
正常范例
1、查询张三账户余额。
select * from account where name = '张三';
2、张三账户余额-1000
update account set money =money - 1000 where name = '张三';
3、李四账户余额+1000
update account set money =money + 1000 where name = '李四';
抛出异常
1、查询张三账户余额。
select * from account where name = '张三';
2、张三账户余额-1000
update account set money =money - 1000 where name = '张三';
抛出异常,张三余额减少,李四余额未增加。
3、李四账户余额+1000
update account set money =money + 1000 where name = '李四';
二、事务操作。
方式一:关闭事务的自动提交
1、查看/设置事务提交方式。
SELECT @@autocommit;#查看事务的自动提交方式(如果为1,是自动提交,如果为0,是手动提交)
SET @@autocommit = 0;#改为手动提交
2、提交事务。
commit;
3、回滚事务。
rollback;
方式二:手动开启事务
1、开启事务
START TRANSACTON 或 BEGIN;
2、提交事务
COMMIT;
3、回滚事务
ROLLBACK;
三、事务的四大特性(ACID)。
1、原子性(Atomic):事务是不可分割的最小操作单元,要么都成功,要么都失败。
2、一致性(consistency):事务完成时,必须所有的数据都保持一致状态。
3、隔离性(isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
4、持久性(durability):事务一旦提交,它对数据库中的数据的改变就是永久的。
四、并发事务引发的问题。
1、脏读:一个事务读到另一个事务还没有提交的数据。
2、不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
3、幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了幻影。
五、事务的隔离级别。
1、RU(read uncommitted),也就是未提交读
对方事务还没有提交,我们当前事务就可以读取到对方未提交的数据
读未提交 存在脏读(Dirty read)现象:表示读到了脏的数据
2、RC(read committed),已提交读(Oracle数据库默认级别)
对方提交之后的数据我方可以读取到
这种隔离级别解决了脏读现象
读已提交存在的问题是:不可重复读
3、RR(repeatable read),可重复读(mysql默认级别)
这种隔离级别解决了不可重复读问题
这种隔离级别存在的问题是:读取到的数据是幻象
4、Serializable,串行(xing)化
解决了所有问题
但是效率低,需要事务排队
事务需要一个一个进行,当一个事务在执行时,其他的事务必须排队等待
当被执行的事务提交之后,才轮到下一个事务,以此类推
隔离级别 | 脏读 | 不可重复读 | 幻读 |
RU,未提交读 | √ | √ | √ |
RC,已提交读(Oracle数据库默认级别) | × | √ | √ |
RR,可重复读(mysql默认级别) | × | × | √ |
Serializable,串行(xing)化 | × | × | × |
查询事务隔离级别
SELECT @@TRANSACTION_ISOLATION
设置事务隔离级别格式
SET [SESSION(当前客户端窗口有效) | GLOBAL(所有客户端窗口有效)] TRANSACTION isolation LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};
示例
set global transaction isolation level 隔离级别;
#示例:改为RC(已提交读)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
#示例:改为RR(可重复读)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
注意:事务的隔离级别越高,数据越安全,但是性能越低,反之,事务的隔离级别越低,数据越不安全,但是性能越高。