Java 性能调优实战
刘超
前金山软件技术经理
59174 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
开篇词 (1讲)
模块一 · 概述 (2讲)
结束语 (1讲)
Java 性能调优实战
15
15
1.0x
00:00/00:00
登录|注册

34 | MySQL调优之事务:高并发场景下的数据库事务调优

可序列化
可重复读
已提交读
未提交读
持久性
隔离性
一致性
原子性
减少锁的持有时间
减小锁粒度
控制事务的大小
避免行锁升级表锁
业务场景与隔离级别
next-key lock
gap lock
record lock
排他锁(X)
共享锁(S)
事务隔离级别
乐观锁
悲观锁
幻读
不可重复读
脏读
数据丢失
InnoDB存储引擎支持事务
MyISAM存储引擎不支持事务
ACID属性
逻辑处理单元
总结
优化高并发事务
锁具体实现算法
InnoDB的锁机制
事务隔离解决并发问题
并发事务问题
MySQL中的事务
数据库事务
高并发场景下的数据库事务调优

该思维导图由 AI 生成,仅供参考

你好,我是刘超。
数据库事务是数据库系统执行过程中的一个逻辑处理单元,保证一个数据库操作要么成功,要么失败。谈到他,就不得不提 ACID 属性了。数据库事务具有以下四个基本属性:原子性(Atomicity)、一致性(Consistent)、隔离性(Isolation)以及持久性(Durable)。正是这些特性,才保证了数据库事务的安全性。而在 MySQL 中,鉴于 MyISAM 存储引擎不支持事务,所以接下来的内容都是在 InnoDB 存储引擎的基础上进行讲解的。
我们知道,在 Java 并发编程中,可以多线程并发执行程序,然而并发虽然提高了程序的执行效率,却给程序带来了线程安全问题。事务跟多线程一样,为了提高数据库处理事务的吞吐量,数据库同样支持并发事务,而在并发运行中,同样也存在着安全性问题,例如,修改数据丢失,读取数据不一致等。
在数据库事务中,事务的隔离是解决并发事务问题的关键, 今天我们就重点了解下事务隔离的实现原理,以及如何优化事务隔离带来的性能问题。

并发事务带来的问题

我们可以通过以下几个例子来了解下并发事务带来的几个问题:
1. 数据丢失
2. 脏读
3. 不可重复读
4. 幻读

事务隔离解决并发问题

以上 4 个并发事务带来的问题,其中,数据丢失可以基于数据库中的悲观锁来避免发生,即在查询时通过在事务中使用 select xx for update 语句来实现一个排他锁,保证在该事务结束之前其他事务无法更新该数据。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

在高并发场景下,数据库事务调优至关重要。本文深入探讨了数据库事务隔离性问题,重点介绍了事务隔离的实现原理以及性能优化方法。首先分析了并发事务可能引发的问题,如数据丢失、脏读、不可重复读和幻读。随后详细讨论了事务隔离解决并发问题的方法,包括悲观锁和乐观锁的应用,以及不同隔离级别的特点和适用场景。此外,还介绍了InnoDB实现的行锁和表锁的具体算法,以及在高并发事务中的优化策略。总的来说,本文通过深入浅出的方式,全面介绍了高并发场景下数据库事务调优的相关知识,对于需要解决高并发数据库事务问题的技术人员具有一定的参考价值。文章内容类似于MySQL的并发事务调优和Java的多线程编程调优,都可以通过减小锁粒度和减少锁的持有时间进行调优。在MySQL的并发事务调优中,建议尽量在可以使用低事务隔离级别的业务场景中,避免使用高事务隔离级别。文章还提出了思考题,引发读者对InnoDB实现原子性、一致性和持久性的思考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 性能调优实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(41)

  • 最新
  • 精选
  • 许童童
    binlog + redo log 两阶段提交保证持久性 事务的回滚机制 保证原子性 要么全部提交成功 要么回滚 undo log + MVCC 保证一致性 事务开始和结束的过程不会其它事务看到 为了并发可以适当破坏一致性

    作者回复: 数据库基础非常扎实,赞

    2019-08-08
    3
    75
  • QQ怪
    默认transaction用的是数据库默认的隔离级别不是一定是RR,只是用MySQL默认是RR

    作者回复: 对的

    2019-08-08
    25
  • L.
    老师,对于可重复读(Repeatable Read)的事务级别可以避免不可重复读的现象有个疑问: 对于事务A来说,它在获得共享锁期间修改了数据,比如把A改为B,修改完成后释放共享锁。在A获得共享锁期间,事务B看到的数据是A,释放共享锁后,事务B才获得排他锁,然后看到的数据是B。两次的数据不一样啊,还是没有避免不可重复读。。。。不知道我理解的哪里不对,望老师指点。。。🙏

    作者回复: 粗略看好像没什么问题,但仔细看就能看出问题了。 事务A存在读和改两个操作,事务B也同样存在读和改两个操作。事务A在读时,由于是共享锁,事务B也能读到该数据,当事务A进行修改就需要上排他锁了,此时事务B由于已经对该数据加了共享锁,事务A需要等待事务B释放共享锁才能获取排他锁来修改数据。同样事务B也在等待事务A释放共享锁。这种操作会导致死锁的出现。 我们一般用一个读的事务操作和一个读写事务操作来理解RR事务隔离级别。

    2019-08-14
    7
    12
  • 和你一起搬砖的胡大爷
    老师能否重点讲一下record lock、gap lock 以及 next-key lock?

    作者回复: 好的,后面安排

    2019-08-08
    3
    7
  • 月迷津渡
    一个问题困扰我挺久希望解答,spring的事务隔离和db的事务隔离机制有什么关系,这么问吧比如db里默认是RR的隔离级别(默认也肯定会有一个隔离级别),我spring的事务里就不用配置隔离级别了?如果spring的事务里的代码并没有db操作我也能设置spring的事务隔离级别? 其次就是设置db级别的事务隔离的话,那如果业务不一样的话是不是理论上可以把库拆开来?因为肯定有一些库用到了不需要的更高隔离级别影响性能。

    作者回复: 文中解释了怎么实现了数据库的事务隔离级别,那就是通过锁来实现的,Spring的封装只是使用了 MySQL提供的标准接口,只要在设置transaction的时候设置事务隔离级别。 如果不想影响不同业务相互之间的性能,可以通过拆库实现。

    2019-10-21
    4
    6
  • 珠穆写码
    老师,您这些数据库的相关知识是从官网还是某些书籍中获取的?我的数据库进阶的知识比较浅,看官网觉得有点费劲,不知道从哪入手去看去学

    作者回复: 可以阅读一些基础入门的书籍,也是作者已经消化梳理过了的,会比较通俗易懂。

    2019-08-28
    2
    5
  • .
    1. 结合业务场景,使用低级别事务隔离 2. 避免行锁升级表锁 3. 控制事务的大小,减少锁定的资源量和锁定时间长度

    作者回复: 每篇都有读后总结,赞一个

    2020-03-21
    4
  • 天天向上
    老是有个问题,希望得到解答:InnoDB引擎下,select语句是不加锁的啊,那在文章中 避免行锁升级表锁一节中,讲到 如果不通过索引条件检索数据,行锁将会升级到表锁,应该不成立啊?

    作者回复: 这里的索引在update也会使用到

    2020-01-11
    3
    3
  • 张三丰
    未提交读(Read Uncommitted):在事务 A 读取数据时,事务 B 读取和修改数据加了共享锁。这种隔离级别,会导致脏读、不可重复读以及幻读。 这句话怎么理解呢?事务B读取和修改数据加了共享锁?修改数据不是只能加排它锁么?

    作者回复: 事务B读取数据加了共享锁,修改数据时加了排它锁

    2019-10-04
    2
    1
  • 风轻扬
    老师,对数据库锁不是很熟悉。以下结构是正确的吗? 数据库锁=乐观锁 + 悲观锁[共享锁、排它锁[行锁、表锁]] 这些是数据库所有的锁吗?

    作者回复: 是的

    2019-09-22
    2
    1
收起评论
显示
设置
留言
41
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部