MySQL事务原理及优化

前言:

        在一些比较严谨业务当中,我们经常会使用事务来保证一致性,那为什么要使用事务呢?这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事 务隔离机制、锁机制、MVCC多版本并发控制隔离机制、日志机制,用一整套机制来解决多 事务并发问题。接下来的,我们一起来理解数据库内部的执行原理。


事务及其ACID属性

事务是一组操作要么全部成功,要么全部失败,目的是为了保证数据最终的一致性。

事务具有以下4个属性,通常简称为事务的ACID属性。

  • 原子性(Atomicity) :当前事务的操作要么同时成功,要么同时失败。原子性由undo log日志来实现。
  • 一致性(Consistent) :使用事务的最终目的,由其它3个特性以及业务代码正确逻辑来实现
  • 隔离性(Isolation) :在事务并发执行时,他们内部的操作不能互相干扰。隔离性由MySQL的各种锁以及MVCC机制来实现。
  • 持久性(Durable) :一旦提交了事务,它对数据库的改变就应该是永久性的。持久性由redo log日志来实现。

并发事务处理带来的问题:

更新丢失(Lost Update)或脏写

  当两个或多个事务选择同一行数据修改,有可能发生更新丢失问题,即最后的更新覆盖了由其他事务所做的更新。

脏读(Dirty Reads)

  事务A读取到了事务B已经修改但尚未提交的数据

不可重读(Non-Repeatable Reads)

  事务A内部的相同查询语句在不同时刻读出的结果不一致

幻读(Phantom Reads)

  事务A读取到了事务B提交的新增数据


事务隔离级别

隔离级别

脏读(Dirty Read)

不可重复读(NonRepeatable Read)

幻读(Phantom Read)

读未提交(Read uncommitted)

可能

可能

可能

读已提交(Read committed)

不可能

可能

可能

可重复读(Repeatableread)

不可能

不可能

可能

可串行化

(Serializable)

不可能

不可能

不可能

        可重复读(Repeatableread)这个隔离级别,记住一句话就能理解:可重复读隔离级别在事务开启的时候,第一次查询是查的数据库里已提交的最新数据,这时候全数据库会有一个快照(当然数据库并不是真正的生成了一个快照,其实是undo日志版本链,MVCC机制属于RR\RC级别特有的),在这个事务之后执行的查询操作都是查快照里的数据,别的事务不管怎么修改数据对当前这个事务的查询都没有影响,但是当前事务如果修改了某条数据,那当前事务之后查这条修改的数据就是被修改之后的值,但是查其它数据依然是从快照里查,不受影响。

查看当前数据库的事务隔离级别: show variables like 'tx_isolation';

设置事务隔离级别:set tx_isolation='REPEATABLE-READ';

Mysql默认的事务隔离级别是可重复读,用Spring开发程序时,如果不设置隔离级别默认用Mysql设置的隔离级别,如果Spring设置了就用已经设置的隔离级别


大事务的影响

  • 并发情况下,数据库连接池容易被撑爆
  • 锁定太多的数据,造成大量的阻塞和锁超时
  • 执行时间长,容易造成主从延迟
  • 回滚所需要的时间比较长
  • undo log膨胀
  • 容易导致死锁

事务优化

  • 将查询等数据准备操作放到事务外
  • 事务中避免远程调用,远程调用要设置超时,防止事务等待时间太久
  • 事务中避免一次性处理太多数据,可以拆分成多个事务分次处理
  • 更新等涉及加锁的操作尽可能放在事务靠后的位置
  • 能异步处理的尽量异步处理
  • 应用侧(业务代码)保证数据一致性,非事务执行

        以上是个人对于mysql的事务理解,如有不足,请多多指教!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值