mysql事务与锁关系目录
一、事务的基础理论
1. 应用场景
应用场景
电商,商城项目中
订单,订单的生成,支付
2. 代码实现
2.1 思路
try
业务逻辑
提交事务
catch
回滚事务
2.2 事务开启
开启事务方式
begin -- 开启事务
start transaction -- 开启事务
COMMIT -- 提交事务
rollback -- 回滚事务
2.3 提交方式
提交方式
mysql 8.0以后可以自动提交
-- 全局查询
show global variables like "autocommit";
-- 局部查询
show session variables like "autocommit"; -- on开启(1),off关闭(0)
修改(修改全局中的"autocommit"设置,只能是当次连接有效,关闭重连后还是配置文件中的设置)
set global autocommit=1; -- 开启自动提交
也可以在配置文件中my.ini中[mysqld]下面的autocommit=1或者0设置
3. 事务需求
要求
innodb 支持事务(主要使用innodb)
myisam 不支持事务,但可以实现伪事务(伪事务通常用于新增,查询)
4. 事务特性
4.1 第一个特性 原子性(Atomicity)
要么一起成功继续执行,要么一起失败回滚事务
4.2 第二个特性 一致性(Consistency)
要保证数据由一种状态转化为另一种状态
4.3 第三个特性 隔离性(Isolation)
互不干扰
4.4 第四个特性 持久性(Durability)
事务通常都是保存在磁盘当中,重做日志会记录因为异常而没有写入的数据,在下一次重启的时候执行重做日志去写入数据
二、事务的生命周期
1. 开启事务
begin – 开启事务
start transaction – 开启事务
2. 创建一个日志文件
3. 执行业务逻辑 =》提交 =》根据实际的sql写入日志文件,但是并没有运行sql
COMMIT – 提交事务
4. 刷新日志
5. 将数据写入到磁盘中,也是sql执行的最终环节
6. 写入checkpoint --(ckp),验证数据从而保证数据的一致性
三、事务的重做日志与回滚日志
1. 重做日志
重做日志
存储位置: 磁盘当中的名称
redo log => ib_logfile(独享表空间)
重做日志存储的是什么:
事务的id
sql语句
执行时间:
在mysql事务执行提交之后,mysql出现了异常(挂掉了),在下一次重启服务的时候执行重做日志,并重新写入数据
如果非自动提交,一直没有手动提交(COMMIT)数据不会丢失,但是会在一定的时间段内自动提交或者是回滚
2. 回滚日志
回滚日志
存储位置:
undo log => ibdata(共享表空间)=> 回滚数据
回滚日志存储的是些什么:
事务的id
操作的数据元素
操作前的数据
操作后的数据
执行时间:
1. 手动执行回滚命令
2.事务执行后,提交前 mysql出现异常(挂掉了),在下一次重启服务的时候执行
须知:
日志先行:日志的优先权大于实际的数据操作,所有会执行的sql先写日志,再写入数据
四、事务日志的详细流程
show engine innodb status\G; --查看储存引擎的状态
4.1 事务日志的执行流程
1. 写操作(insert、delete、alter、update)
2. 缓存数据(不是查询缓存而是innodb缓存在内存里面的,查看是否存在)
3. 与磁盘或者是database做沟通,查找数据,并且返回数据到innodb缓存中
4. 进入innodb日志缓存区域
5. 进入innodb日志缓存区域中的重做日志(记录数据),在进入回滚日志(刷新数据到磁盘中)中
6. 提交
7. 先把日志文件刷新到磁盘中,
8. 写入数据
4.2 事务日志存储数据
五、 事务使用建议
innodb存储引擎由于实现了行级锁,颗粒更小,实现更复杂。但是innodb行锁在并发性能上远远要高于表锁页锁。在使用方面可以尽量做到以下几点;
1. 控制事务大小,减少锁定的资源量和锁定时间长度。
2. 人所有的数据检索都通过索引来完成,从而避免因为无法通过索引加锁而升级为表锁。
3. 减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的数据。
4. 在业务条件允许下,尽量使用较低隔离级别的事务隔离。减少隔离级别带来的附加成本。
5. 合理使用索引,让innodb在索引上面加锁的时候更加准确。
6. 在应用中尽可能做到访问的顺序执行
7. 如果容易死锁,就可以考虑使用表锁来减少死锁的概率