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

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

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

并发事务带来的问题

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

事务隔离解决并发问题

以上 4 个并发事务带来的问题,其中,数据丢失可以基于数据库中的悲观锁来避免发生,即在查询时通过在事务中使用 select xx for update 语句来实现一个排他锁,保证在该事务结束之前其他事务无法更新该数据。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 性能调优实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(41)

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

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

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

    作者回复: 对的

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

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

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

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

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

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

    4
    6
  • 咬尖月牙儿
    老师,您这些数据库的相关知识是从官网还是某些书籍中获取的?我的数据库进阶的知识比较浅,看官网觉得有点费劲,不知道从哪入手去看去学

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

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

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

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

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

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

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

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

    作者回复: 是的

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