1、什么是事务,为什么需要事务

事务(Transaction)是数据库并发控制的不可分割的基本单位,可以将一系列的数据库操作集合到一个事务中,从总体上来讲这个事务可能会对数据库进行一些变动。事务存在的意义在于多个同时事务执行完成以后不管成功与否都要保持数据的干净、有序,也就是数据的一致性。比如我们在 12306 上购买火车票,如果付款成功我们将获得金钱 -1、火车票 +1,如果付款失败则金钱 -0、火车票 +0 。所以你有没有想过去找找免费购票的漏洞?

2、事务的四大特性ACID

ACID四大特性是事务的基本特性,其保证了上面的买票行为能正确执行。

2.1 原子性

事务要么成功,要么失败,如果失败则所有对数据库的操作都没有执行。如果在执行过程中出现异常错误,则所有执行都取消,否则就会对数据库产生副作用,造成数据“污染”。Mysql 原子性实现的基础是 undo log。

1BEGIN;
2INSERT INTO xx_table (id, name) VALUES (1, 'a');

上述操作在事务开启后,如果 commit 则应该更改数据记录,如果失败则可以通过 rollback 回滚到之前的状态。

2.2 持久性

都事务成功执行,则所有对数据库的修改都需要持久化的磁盘上,即使中途出现断电、宕机、重启等异常情况,否则就会出现数据不一致。Mysql 持久性实现的基础是 redo log。

1BEGIN;
2INSERT INTO xx_table (id, name) VALUES (1, 'a');
3COMMIT;

上述事务成功执行后应该保证数据可以准确无误的落入磁盘中,即使出现异常情况。

2.3 隔离性

当多个事务同时执行时会出现互相争夺同一资源,也可能同时修改同一数据,这就需要保证各个数据之间能合理的执行自身的操作,同时不影响另一事务执行,最后还要尽可能提高并发执行的性能。Mysql 根据性能和并发安全性实现了4个隔离级别,级别越高并发执行能力越低,并发安全性越高:

  • 读未提交 READ UNCOMMITTED
  • 读已提交 READ COMMITTED
  • 可重复读 REPEATABLE READ
  • 串行 SERIALIZABLE

Mysql 的隔离性是通过锁、多版本并发(MVCC)实现的。

2.4 一致性

保证数据的一致性正是数据库最重要的部分,Mysql 正是通过原子性、持久性和隔离性来保证了数据的一致性。

3、Mysql 如何实现事务

3.1 undo log (回滚日志)

如何保证事务失败情况下时间能倒流呢?一个简单的办法就是拿个小本本把事务中每一个操作记下来,如果出现异常就可以照着改回来就好了。Mysql 的 undo log 就是这个小本本,当事务开启后,mysql 会把相应的每一个的操作记录到内存中,再从内存持久化到硬盘中。而且undo log持久化到硬盘是在数据库变更之前执行完成的,这样即使中途出现断电等情况,重启后依然可以更加 undo log 就行回滚。

Mysql undo log 有两个特点:

  • 每个修改、删除语句都有一条对应的 undo log,并且 undo log 先于数据持久化到磁盘;
  • undo log 是逻辑日志,相当于回滚的是执行的逆向操作,如果数据 update 了,则重新 update 到原来的状态,删除了则重新生成。

undo log 保证了单个事务的原子性

3.2 redo log (重做日志)

当事务成功提交后需要保证数据变更能准确到落到磁盘中,假设这一过程中被拔了电源改怎么办?Mysql 写数据是先写到内存缓存区中 (buffer pool)中,然后由后台线程定期将数据由内存搬到磁盘中,所以一断电内存中的数据就没了。好记性不如烂笔头,同样一个简单的办法就是拿出我们的小本本记下来,等重启了就照着小本本重新执行一次就可以了,这就是 mysql 的 redo log。

redo log 从缓存到磁盘这一过程是同步的,redo log 保证了事务的持久性。

3.3 Mysql 锁和 MVCC

3.3.1 Mysql 锁

类似于多线程中的锁技术,Mysql 中的锁可以用来解决多个请求更改同一数据问题,这是一种常用的并发控制手段,锁可以解决数据不一致问题,同时也降低了并发性能。Mysql 有两种锁来控制并发操作:共享锁排他锁

1、共享锁 (share lock),读锁: 读锁可以共享,多个读请求可以并发执行;
2、排他锁 (exclusive lock),写锁:写锁会排斥其他所有获取锁的请求,一直阻塞至操作完成释放锁。

加读锁方法:

1SELECT * FROM xx_table WHERE id = 1 LOCK IN SHARE MODE;

加写锁方法:

1SELECT * FROM xx_table WHERE id = 1 FOR UPDATE;

3.3.2 Mysql MVCC

单纯使用锁来解决并发安全问题可能会发幅度降低性能,Mysql 引入了另外一种机制,多版本并发控制(MVCC)。当某一个事务连接到mysql后,它所查询到的数据为当前时刻的快照,其他事务对同一数据的更改并不会影响到当前事务的查询。也就是其他事务的变更操作在未提交之前对当前事务都是不可见的。

Mysql 会在每一张表后面隐式的添加三列,其中两列(DB_TRX_ID,DB_ROLL_PT)和 mvcc 有关,这两列标注了此行数据变更或被删除的事务id或时间戳。当事务变更、删除某一数据时,mysql 并不会真正执行操作,只是在相应的列做好标记,表示数据已经被更改,其他事务读到的仍是原来的老数据。

通过 mvcc 就可以解决读操作不一致问题(脏读),避免了锁带来的巨大开销

3.4 Mysql 事务隔离级别实现

Mysql 实现了四个级别的事务隔离,开发者可以针对不同的场景选择合适的事务隔离级别,已达到性能与安全之间的平衡。

读未提交 READ UNCOMMITTED

在这一级别,当前事务可以读取到其他事务未提交的数据,这样做的坏处是脏读,好处是不需要任何锁,可以做到读写并行,大幅度提高并发性能。

读已提交 READCOMMITTED

一个未提交的事务对当前事务是不可见的,当前事务可以读取到已经提交的变动,在实际开发中,大多数场景都使用此级别。Mysql 的读已提交使用排它锁和 mvcc 实现,实现了读写分离,但是会产生不可重复读幻读问题。

可重复读 REPEATABLE READ

这是 mysql 的默认隔离级别,单个事务内读取的结果是不变的,解决了脏读、不可重复读问题,但是仍存在幻读问题(mysql 通过 next-key lock 避免了幻读),此级别可以使用读写锁实现,也可以采用 mvcc 实现,采用读写锁逻辑简单但只能串行执行,采用写锁+ mvcc 实现复杂但可以读写分离。

串行读 SERIALIZABLE:

严格采用读写锁实现,所有操作全部串行执行,不会造成数据不一致问题,但并发性能极差。

3.5 一致性的实现

Mysql 正是通过原子性、持久性和隔离性,保证了数据的一致性。

参考资料

  • 『浅入浅出』MySQL 和 InnoDB
  • 『浅入深出』MySQL 中事务的实现
  • 【MySQL(5)| 五分钟搞清楚 MVCC 机制】
  • Mysql事务实现原理

mysql 并发性_MySQL 事务相关推荐

  1. mysql并发提交事务_Mysql事务并发问题解决方案

    在开发中遇到过这样一个问题 一个看视频记录,更新到100就表示看完了,后面再有请求不继续更新了. 结果是: 导致,里面很多数据出现问题. 推测是以下的情况才会导致 第一条请求 事务在执行中,还未提交( ...

  2. mysql show 原理_mysql事务的实现原理

    此篇文章算是对mysql事务的一个总结,基本把mysql事务相关的知识点都涵盖到了,面试问来问去无非也就是这些,在了解这些之前我们先对mysql在执行的过程中  有一个整体的认识,如下图 如上图所示, ...

  3. java mysql实现原理_MySQL事务实现原理

    MySQL事务隔离级别的实现原理 知识储备 只有InnoDB支持事务,所以这里说的事务隔离级别是指InnoDB下的事务隔离级别 隔离级别 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏 ...

  4. mysql+nest+嵌套事务_MySQL——事务

    事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致状态转换为另一种一致状态. 关键词事务四大特性ACID MySql事务隔离级别 MVCC多版本并发控制实现方 ...

  5. mysql ib_logfile 数量_Mysql 事务日志(Ib_logfile)

    mysql的innodb中事务日志ib_logfile(0/1) 概念: 事务日志或称redo日志,在mysql中默认以ib_logfile0,ib_logfile1名称存在,可以手工修改参数,调节开 ...

  6. 一台mysql并发能力_mysql怎么支撑百万级并发-对于同一个表,MySQL支持多少个并发操作...

    到服务器的SQL最大并发连接数为16384.mysql百万级数据查询. 受服务器配置和网络环境的限制,实际服务器支持的并发连接数量会更小. MySQL流量大,并发问题高 因为mysql是一个线程的连接 ...

  7. mysql 开启事物_mysql事务的开启

    mysql事务的开启 对于一个MYSQL数据库(InnoDB),事务的开启与提交模式无非下面这两种情况: 1>若参数autocommit=0,事务则在用户本次对数据进行操作时自动开启,在用户执行 ...

  8. mysql 并发死锁_Mysql并发时经典常见的死锁原因

    Mysql并发时经典常见的死锁原因 更新时间:2017-06-07 00:17:21 1256次阅读 评论 0 1.mysql都有什么锁 MySQL有三种锁的级别:页级.表级.行级. 表级锁:开销小, ...

  9. mysql事物 总结_Mysql事务总结

    数据库 事务的特性ACID 事务(Transaction)是并发控制的基本单位. 所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐 ...

最新文章

  1. Git基本命令和GitFlow工作流
  2. Jquery empty() remove() detach() 方法的区别
  3. 删除msconfig启动项不打勾的东西
  4. java,倒置后的顺序为3,2,1_java 程序设计题库
  5. android removeRule的使用
  6. Java中list对象的三种遍历方式
  7. TrashFlash卡是什么
  8. [PHP]Yii rules常用规则
  9. 剑指offer-面试题37:序列化二叉树及二叉树的基本操作和测试
  10. android开源人脸识别插件,face-android-demo
  11. 傅里叶变换 matlab FFT 函数解析
  12. Javascript跨域和Ajax跨域解决方案总结
  13. matlab画直方图并拟合泊松分布,将泊松分布拟合为数据(直方图+直线)
  14. 短进程优先调度算法c语言spf,短进程优先的调度算法详解
  15. java的fprintf_fprintf不接受一个字符数组吗?
  16. Excel-事件(Workbook、Worksheet、Range、OnKey/OnTime)
  17. python短信验证码登录_玩转python之获取短信验证码
  18. 计算机系统权限授权,win 7 期间版操作系统的权限说明
  19. PS动作一键设计数字科技未来海报效果
  20. 仿微信图片查看器入场退场动画

热门文章

  1. Linux vi/vim教程
  2. 大数据开发笔记(十):Hbase实践
  3. 大数据分析有哪些分析模型
  4. BI工具的优势存在于哪些方面
  5. 大数据分析平台建模及建议
  6. 传感器的定义、构成、分类
  7. c语言 搜索彩票期数,根据福利彩票的规则用c++编写一个买彩票开奖的程序,求程序代码,谢谢...
  8. python类似turtle的库_Python库——turtle
  9. easypoi 大数据 百万_scrapy 解决爬虫IP代理池,百万大数据轻松爬取。
  10. 事务超时时间无效_架构设计 | 基于消息中间件,图解柔性事务一致性