Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

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

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

并发事务带来的问题

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

事务隔离解决并发问题

以上 4 个并发事务带来的问题,其中,数据丢失可以基于数据库中的悲观锁来避免发生,即在查询时通过在事务中使用 select xx for update 语句来实现一个排他锁,保证在该事务结束之前其他事务无法更新该数据。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(24)

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

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

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

    作者回复: 对的

    2019-08-08
    7
  • 胡峣
    老师能否重点讲一下record lock、gap lock 以及 next-key lock?

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

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

    作者回复: 文中解释了怎么实现了数据库的事务隔离级别,那就是通过锁来实现的,Spring的封装只是使用了 MySQL提供的标准接口,只要在设置transaction的时候设置事务隔离级别。

    如果不想影响不同业务相互之间的性能,可以通过拆库实现。

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

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

    2019-08-28
    1
  • Geek_f6fba7
    老师,您说MVCC 对普通的 Select 不加锁,那RC和RR级别不一样了吗?这两个不就是select加锁不一样吗?还有既然RC select也是快照读,那是不是也解决了不可重复读问题?
    望解答,研究了一晚上Mvcc搞晕了

    作者回复: 这对于普通的select操作是不加锁的,不论事务隔离级别。

    2019-12-04
  • 平凡之路
    老师,您好,我在可重复读里面,事务A没有结束,不做修改操作,但是事务B也可以修改数据

    作者回复: 检查下自己的代码以及隔离级别

    2019-12-03
  • 黎波拉小建
    有个问题请教下,我看到说 redolog 为了提升持久化的IO效率而产生,把每次事务写数据文件改成写redoLog然后再批量写redoLog到数据文件。我就有个问题了,redoLog和数据文件不都是磁盘读么?并且写redolog也需要在事务中同步写,因为异步写不能保证redolog必定写成功。。。求教

    作者回复: 在40讲中,讲到了redo log的工作原理,redo log 又包括了内存中的日志缓冲(redo log buffer)以及保存在磁盘的重做日志文件(redo log file),前者存储在内存中,容易丢失,后者持久化在磁盘中,不会丢失。

    MySQL支持用户自定义在commit时如何将log buffer中的日志刷log file中。这种控制通过变量 innodb_flush_log_at_trx_commit 的值来决定。该变量有3种值:0、1、2,默认为1,即每提交一次事务都写到磁盘中,而设置为0时,为每秒将事务写到磁盘中。

    2019-10-11
    1
  • ASCE1885
    Serializable 翻译为 可串行化 会更合理一些。

    作者回复: 收到建议

    2019-10-10
  • 张三丰
    未提交读(Read Uncommitted):在事务 A 读取数据时,事务 B 读取和修改数据加了共享锁。这种隔离级别,会导致脏读、不可重复读以及幻读。

    这句话怎么理解呢?事务B读取和修改数据加了共享锁?修改数据不是只能加排它锁么?

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

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

    作者回复: 是的

    2019-09-22
  • godtrue
    请问老师数据库的事务本质是不是都是利用单库的事务机制实现的?分布式数据库事务,只是将控制事务提交或回滚的动作往上层提升啦?

    作者回复: 是的

    2019-09-14
  • 小学生🍭
    老师update语句是行锁,那insert语句是什么锁呢

    作者回复: 也是行锁

    2019-09-10
  • 加载中……
    老师好,有个问题请教下。文章中说:“可重复读(Repeatable Read)可以避免脏读、不可重复读,但依然存在幻读的问题。”
    我之前了解的是,SQL标准不要求RR解决幻读,但InnoDB的 RR下 是不会产生幻读的。
    而且自己实验也是InnoDB在RR下没有幻读的现象。操作如下:
    sessionA: begin;
    sessionA: select * from t where id>1;(2条记录)
    sessionB: insert into t(id,a) values(5,5);
    sessionA: select * from t where id>1;(还是2条看不到5,5。没有产生幻读)

    作者回复: 这是RR下使用的间隙锁,所以不会出现幻读

    2019-08-29
    3
  • 小布丁
    老师数据库的事务和Spring的事务是一回事吗?写业务代码的时候,两种不同的事务分别起什么作用呢?或者说控制范围有何不同呢?

    作者回复: 两者实际上是一回事,Spring的事务也是基于数据库事务封装的方法。

    2019-08-23
  • 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
    1
  • Liam
    老师好,查询未加索引时行锁升级为表锁这里有个疑问,mvvc机制下select不是不加锁吗?除非是in share mode或for update

    作者回复: 对的

    2019-08-12
  • 星星滴蓝天
    老师能否多讲点innodb锁。最近我们老是出现锁等待的情况,老师可否给一些优化的思路

    作者回复: 嗯嗯,后面会讲到死锁和锁等待的问题

    2019-08-09
  • 苏志辉
    RR是基于MVVC的,而后者对于select不加锁,那么如果事务a有两次查询,事务b在a的两次查询之间做了修改,要保证可重复读,a两次读取的都是b改之前的快照吗?

    作者回复: 对的,快照版本不大于事务版本号

    2019-08-09
  • LW
    思考题:通过redo log和undo log实现

    作者回复: 对的,redo log保证事务的原子性以及持久性,undo log保证事务的一致性。

    2019-08-08
收起评论
24
返回
顶部