mysql事务

ACID

   原子atomicity不可分、一致性状态consistency数据完整性、隔离isolation不影响其他事务、持久性durability写入磁盘

  存放数据的文件data file,缓存数据buffer,操作先作用缓存,缓存满了或其他情况写入磁盘

  日志也是有缓存的,一般追加内容

redo和undo日志

   undo日志记录某数据被修改前的值,事务失败后rollback恢复数据,redo日志记录被修改后的数据,恢复未写入磁盘的数据

   原子、稳定、持久的依赖;redo_buf undo_buf缓存,先存缓存在将*_buf写到undo

   undo记录数据事务开始前的值,事务失败或rollback可通过undo来回复记录

   redo记录修改后的日志,数据不必在事务提交前写入到磁盘,减少IO

A 事务开始
B 记录AA=3到undo_buf
C 修改AA=1 记录redo_buf
D 记录BB=5到undo_buf
E 修改BB=7 记录redo_buf
F 将undo_buf写到undo(磁盘)
G 将redo_buf写到redo(磁盘)
H 将data_buf写到datafile(磁盘)
I 事务提交

事务在F前崩溃数据没写入磁盘都在内存,恢复后重新从磁盘载入之前的数据,不会被破坏
G前崩溃使用redo恢复
G前回滚使用undo完成
回滚的事务恢复时的操作:先redo在undo

 

隔离级别:

   通过锁机制实现,innodb细粒度行级锁,锁定索引实现隔离

       查询条件中有主键锁住主键,有索引则先锁定索引再锁定主键(可能造成死锁),无索引锁定表

isolation_default是plafromTransactionManager默认隔离级别
与JDBC隔离级别相对应:
  1、isolation_read_uncommitted最低级别,不用锁,有脏读、不可重复读、幻读问题
  2、isolation_read_committed读已提交,读不加锁,增删改加锁,因此避免脏读,但有不可重复读、幻读
  3、isolation_repeatable_read可重复读,读写都加锁,有幻读问题
        其他事务须等待本事务释放锁才操作相同数据
  4、isolation_serializable串行化,避免脏读、不可重复读、幻读

脏读:可读取到其他事务未提交的数据
不可重复读:一事务中两个相同sql读取内容可能不一样,修改导致数据不一致
幻读:一事务中发现新数据,比如增加了些数据

 

表锁以查询为主,只有少量按索引条件更新数据的应用

行锁有大量按索引条件并发更新少量不同数据且有并发查询的应用

 

表锁

锁定一张表,逻辑简单开销小,获取释放速度快、锁住一张表避免死锁但是并发读低

表共享读锁table read lock 表独占写锁table write lock

  myISAM读操作不会阻塞其他用户读请求阻塞写操作,写操作阻塞其他用户对同一表的读和写操作

       读与写间、写与写间是串行的

 优化

  执行时间尽可能短:避免大/复杂query,高效索引,让myisam存必要信息控制字段类型

  读写优先级,默认写高于读

       例子update low_priority article set click_num=134 where id=1 ;low_priority使系统认为update优先级低于update,先执行读

       mysql调整策略

            1、low_priority应用于delete insert 、load data、replace 和update 

            2、high_priority应用于select insert语句

            3、delayed关键字应用于insert 、replace语句

行锁

  粒度小争用率低并发高,实现复杂开销大,加锁慢易死锁

  主要是innodb、NDBCluster引擎,实现方式:

行锁通过给索引加锁实现,无索引通过隐藏的聚簇索引对记录加锁
sql操作了主键索引mysql锁定对应主键索引
sql操作了非主键索引,mysql先锁定非主键索引在锁定对应主键索引
优化:
  1、减少基于范围的数据检索
  2、控制事务大小,使用低级别的事务隔离
  3、类似业务中采用相同的sql访问顺序、一次锁定锁需要的资源、易死锁的业务升级锁定粒度:表锁

细分种类

共享shared and排他 exclusive locks

innodb引擎实现的标准行级锁,

共享锁select * from user where id = 1 lock in share mode;

排他锁select * from user where id =1 for update;

意向锁 intention locks

表级别的锁,据意向锁判断表是否有行被锁定确定是否可以加锁成功,如果是行锁遍历判断,表锁判断一次

当发现要用的资源被其他锁占用加意向锁,说明事务稍后会给该资源加*类型的锁,使得行锁与表锁共存

当一个事务对表加了意向排他锁,其他事务加锁前通过该表的意向排他锁有事务进行独占操作,从而等待

 

记录锁record locks

索引记录上的锁,select id from user where id =1 for update;阻止其他事务对id=1行进行增删改操作

锁定索引记录,如没有定义索引,锁定隐式的聚集索引

间隙锁gap locks

间隙锁是在一个索引记录间的间隙上的锁,可跨域多个索引值,为空

    向数据记录的第一个索引键前和最后一个索引键后的空域空间上标记锁定信息

    

使用唯一索引来搜索唯一行的语句,只加记录锁不加间隙锁(不包括组合唯一索引)

临键锁next key locks

行锁与间隙锁组合,innodb扫描索引记录时,先对选中索引记录加记录锁,在对索引记录两边间隙加上间隙锁

自增锁

事务插入到有自增列的表中而获得的一种特殊表级锁

一个事务正向表中插入值,其他事务必须等待,保证插入的行是连续自增值

这里写图片描述

死锁

innodb的事务管理和锁定机制中,有专门检测死锁的机制,产生死锁后短时间内检测到死锁的存在

   回滚较小的事务:事务插入、更新、删除的数据量

 

mvcc multi-verson 从currency control

多版本并发控制,行级锁的变种,避免加锁操作

通过每行记录后保存行的创建时间和过期时间或删除时间

    (都隐藏的,其实是系统的版本号),开始新的事务,版本号自动增加

原理:

select时

   innodb查询时检查1,数据行的版本号早与当前事务的版本号;2,行的删除版本号要么无要么大于当前事务版本号

insert/delet

   将当前系统版本号作为新插入、删除的行的版本号

update

   新插入一行数据,将当前系统版本号作为行的版本号、作为原来行的删除版本号

   更新主键,聚集索引和普通索引都将产生两个版本,更新非主键只普通索引产生两个版本

mvcc只在read committed 和repeatable read两个隔离级别下工作

 

事务操作

mysql默认开启autocommit模式,将每条语句当做事务处理,每条sql自动被提交

使用begin或start transcation 会将 自动提交 挂起,直到显示调用 commit 

 

事务传播行为

     propagation behavior

    propagation_required:支持当前事务,如当前无、新建,有加入当前
    
    propagation_supports:支持当前事务,如当前无、非事务方式执行,有加入当前
    
    propagation_mandatory:支持当前事务,如当前无  异常
    
    propagation_requires_new:新建事务,当前存在则当前挂起
        使用JtaTransactionManager管理器,更像是两个独立的事务,互不影响,内层有自己的隔离级别和锁
        
    propagation_not_supported:非事务方式执行,当前存在 挂起,使用JtaTransactionManager管理器

    propagation_never:非事务方式执行,当前存在 异常
    
    propagation_nested:当前存在事务 嵌套事务运行,嵌套事务独立当前事务:回滚 提交,当前事务无 与required同
        嵌套事务一个非常重要的概念就是内层事务依赖于外层事务
            外层事务失败时,会回滚内层事务所做的动作
            内层事务操作失败不会引起外层事务的回滚


https://blog.csdn.net/weixin_39625809/article/details/80707695    

 

用法:
    

@Transactional(
    readOnly = false, //读写事务
    timeout = -1 ,     //事务的超时时间,-1为无限制
    noRollbackFor = ArithmeticException.class, //遇到指定的异常不回滚
    isolation = Isolation.DEFAULT, //事务的隔离级别,此处使用后端数据库的默认隔离级别
    propagation = Propagation.REQUIRED //事务的传播行为
)

 

https://www.iteye.com/topic/35907
https://www.cnblogs.com/mcahkf/p/9228609.html简易

https://blog.csdn.net/zcl_love_wx/article/details/83305645

https://blog.csdn.net/zcl_love_wx/article/details/81983267
https://blog.csdn.net/qq_33101675/article/details/83012379实例

https://www.letiantian.me/2014-06-18-db-undo-redo-checkpoint/

https://blog.csdn.net/weixin_39625809/article/details/80707695详情

事务常用命令:suspend挂起,commit提交,resume恢复,rollback回滚

 

https://blog.csdn.net/weixin_37934748/article/details/82774230?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase

 

https://blog.csdn.net/sk199048/article/details/50596092?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

https://www.cnblogs.com/Bozh/archive/2013/03/18/2966494.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值