什么是事务?
- 事务是指将多条 SQL 语句作为一个整体执行,要么全部成功,要么全部失败,确保批量处理的“增、删、改”操作保持一致性。
事务相关的术语:
- 开启事务:
START TRANSACTION
- 事务结束:
END TRANSACTION
- 事务提交:
COMMIT TRANSACTION
- 事务回滚:
ROLLBACK TRANSACTION
事务的四大特征
- 原子性:事务必须是一个不可分割的操作,要么全部成功,要么全部失败。
- 持久性:一旦事务提交,对数据库的更改就是永久的,后续操作或故障不会影响已提交的事务。
- 隔离性:多个事务同时执行时,相互之间不能干扰,以避免数据不一致。
- 一致性:事务执行的结果必须使数据库从一个一致状态转换到另一个一致状态。
-
事务的四大特征
- 原子性:事务必须是一个不可分割的操作,要么全部成功,要么全部失败。
- 持久性:一旦事务提交,对数据库的更改就是永久的,后续操作或故障不会影响已提交的事务。
- 隔离性:多个事务同时执行时,相互之间不能干扰,以避免数据不一致。
- 一致性:事务执行的结果必须使数据库从一个一致状态转换到另一个一致状态。
-
MyBatis 的事务管理
什么是事务?
- 事务是指将多条 SQL 语句作为一个整体执行,要么全部成功,要么全部失败,确保批量处理的“增、删、改”操作保持一致性。
事务相关的术语:
- 开启事务:
START TRANSACTION
- 事务结束:
END TRANSACTION
- 事务提交:
COMMIT TRANSACTION
- 事务回滚:
ROLLBACK TRANSACTION
-
事务的四大特征
- 原子性:事务必须是一个不可分割的操作,要么全部成功,要么全部失败。
- 持久性:一旦事务提交,对数据库的更改就是永久的,后续操作或故障不会影响已提交的事务。
- 隔离性:多个事务同时执行时,相互之间不能干扰,以避免数据不一致。
- 一致性:事务执行的结果必须使数据库从一个一致状态转换到另一个一致状态。
- 持久性:
- 内存无法永久性存储数据,因此在出现故障时,缓存中的数据可能无法及时写回磁盘。未配置事务的 SQL 语句可能会放弃数据的持久化。而配置了事务的 SQL 语句将确保缓存中的数据被持久化到磁盘。
- 事务如何实现持久性?通过重做日志:一旦主机重新启动,可以通过重做日志恢复数据并将其写回磁盘。
如何使用事务???
#张三给李四转账100
#非事务提交
UPDATE act SET money = 400 WHERE id = 2;
UPDATE act SET money = 200 WHERE id = 1;
#执行失败
UPDATE act set money = 400 WHERE id = 2;
UPDATE act est money = 200 WHERE id = 1w; #模拟第二条语句出现错误
#执行成功
START TRANSACTION;
UPDATE act set money = 400 WHERE id = 2;
UPDATE act set money = 200 WHERE id = 1;
commit;
#执行失败
START TRANSACTION;
UPDATE act set money = 400 WHERE id = 2;
UPDATE act set money = 200 WHERE id = 1w;
rollback;
#一旦事务开启,我们就需要一个判断
#如果执行成功则commit提交事务,将事务持久化保持,一旦执行失败,就rollback回滚,数据库恢复为原来的状态
事务的隔离级别
MySQL 默认的事务隔离级别为“可重复读”。为了观察并发事务产生的问题,可以将 MySQL 的事务隔离级别设置为“读未提交”。
set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
-
隔离性:多个事务同时执行会产生的问题
并发问题
-
脏读:事务 A 读取到了事务 B 修改但未提交的数据。
-
不可重复读:在同一个事务内,多次读取同一个数据,但是数据的值发生改变
-
幻读:指的是在一个事务中,多次查询同一个范围的数据,却发现有新增或者减少的行。
这是因为在这个事务进行的过程中,另一个事务插入或者删除了符合查询条件的数据,导致前后两次查询结果不一致
-
#现在做一次脏读 SELECT *FROM t_user; #模拟事务A #脏读:事务A读取到了事务B修改但是没有提交的数据 START TRANSACTION ; SELECT *FROM t_user; SELECT *FROM t_user;
#现在做一次脏读 SELECT *FROM t_user; #模拟事务B #脏读:事务A读取到了事务B修改但是没有提交的数据 START TRANSACTION ; UPDATE t_user SET money = 700 WHERE id = 1; #commit未提交 事务A读取到了700
-
set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;
修改后,未提交的事务无法查询,确保了安全性