MySQL事务
一、事务
- 数据库的事务是一种机制,一个操作序列
- 事务把一组操作命令视为一个整体,要么全部执行成功,要么都执行失败,只要有一个失败,就无法成功
- 事务是一个不可分割的工作逻辑单元
二、事务四大特征
- 原子性(Atomicity
/ætəˈmɪsəti/
):事务是不可分割的最小操作单位,要么同时成功,要么同时失败。 - 一致性(Consistency
/kənˈsɪstənsi/
):事务完成时,必须使所有的数据都保持一致状态(事务按照预期生效,事务完成时数据的状态是预期的状态,即事务完成前后的数据都必须保持正确状态
) - 隔离性(lsolation) :事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离
- 持久性(Durability
/ˌdjʊərəˈbɪlɪti/
):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的,接下来即使数据库发生故障也不应该对其有任何影响。
MySQL数据库事务为默认提交,但是我们可以设置为手动提交
-- 查看事务的默认提交方式。返回 1 则是自动提交,返回 0 则是手动提交,该设置只对当前会话有效
SELECT @@autocommit;
--修改事务提交方式
set @@autocommit = 0;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
操作方式二:
开启事务:
START TRANSACTION 或 BEGIN TRANSACTION;
提交事务:
COMMIT;
回滚事务:
ROLLBACK;
操作实例:
在开启事务后,事务中出现错误,还没commit之前,在本窗口查询出来的结果是执行sql语句之后的结果,但是当我们再打开一个查询窗口,会发现结果还是执行sql语句之前的结果
START TRANSACTION;
update user set username = '刘德' where id = 21;
ksjadlks出错了
update user set username = '张丰' where id = 26;
当前窗口查询结果
其他窗口查询的结果,显示的还是之前的结果,执行的sql语句并没有生效
若想当前执行的sql语句生效,则需执行commit,若不想要错误执行的结果,可以使用roolback回滚事务,使其回到执行sql语句之前的状态
begin;-- 开始事务,可用 start transaction替代
update user set username = '刘德华' where id = 21;
ksjadlks出错了
update user set username = '张三丰' where id = 26;
commit; -- 提交事务
rollback; -- 回滚事务
注意:一旦提交或回滚事务之后,数据将被持久化到数据库,即数据被真正的写入数据库中,无法回退,只能另行修改
三、并发事务
并发事务可能会出现的问题:
问题 | 描述 |
---|---|
脏读 | 一个事务读到另一个事务还没提交的数据 |
不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同 |
幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在 |
这三个问题的详细演示:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=55cd
并发事务隔离级别:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed(oracle默认) | × | √ | √ |
Repeatable Read(MYSQL默认) | × | × | √ |
Serializable | × | × | × |
- √表示在当前隔离级别下该问题会出现
- Serializable 性能最低,只能单线程;Read uncommitted 性能最高,数据安全性最差
查看事务隔离级别:
SELECT @@TRANSACTION_ISOLATION;
设置事务隔离级别:
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效
-- 将当前会话的事务隔离级别设置为read committed
set session transaction isolation level read committed;