MVCC - undo log 版本链数据访问规则
MVCC - undo log 版本链数据访问规则
课程视频中列出的 undo log 版本链数据访问规则有误,其中第 3 条和第 4 条应改为如下:
下面举例说明不同规则的触发情况
第 1 条规则和第 2 条规则现在表中存在一条记录:
id
age
name
db_trx_id
db_roll_ptr
30
30
A30
1
null
接下来,数据库进行了事务操作,此时隔离级别是 RC 或 RR:
事务2
事务3
开启事务
开启事务
修改 age 为 3
(1) 查询记录,生成 readview2
(2) 查询记录,生成 readview1
提交事务
提交事务
在查询 (1) 和 (2) 执行时,生成的 undo log 版本链以及 readview 如下:
addr
id
age
name
db_trx_id
db_roll_ptr
>
30
3
A30
2
0x01
0x01
30
30
A30
1
null
readview1
readview2
m_id ...
synchronized 原理
synchronized 原理
本文是对于 死磕Synchronized底层实现 系列的个人补充
死磕Synchronized底层实现—概论
死磕Synchronized底层实现—偏向锁
死磕Synchronized底层实现—轻量级锁
死磕Synchronized底层实现—重量级锁
优秀博文推荐关于 synchronized 原理的解析众说纷纭,尤其是 jdk1.6 以后引入的相关锁优化的内容。
远古巨著 Java Concurrency in Practice 出版时间较早,因此没有锁优化的内容讲解。
:star::star::star: 深入理解 Java 虚拟机(第 3 版) 最后一个章节对锁优化的内容做了讲解,并给出了一张经典的关系图,如下:
但是毕竟是 JVM 的书籍,锁优化内容的讲解相对来说还是较简略的。
下面是在网络上找到的一些讲解 synchronized 原理的优秀博文:
:star::star::star::star::star: 死磕Synchronized底层实现:该系列总共有四篇文章,基于 Hotspot jdk8u 源码讲解,至少第一篇概论是需要完 ...
好文收录 - 死磕Synchronized底层实现--重量级锁
死磕Synchronized底层实现—重量级锁
原文链接:死磕Synchronized底层实现—重量级锁
本文为死磕Synchronized底层实现第四篇文章,内容为重量级锁实现。
本系列文章将对HotSpot的synchronized锁实现进行全面分析,内容包括偏向锁、轻量级锁、重量级锁的加锁、解锁、锁升级流程的原理及源码分析,希望给在研究synchronized路上的同学一些帮助。主要包括以下几篇文章:
死磕Synchronized底层实现—概论
死磕Synchronized底层实现—偏向锁
死磕Synchronized底层实现—轻量级锁
死磕Synchronized底层实现—重量级锁
更多文章见个人博客:https://github.com/farmerjohngit/myblog
重量级的膨胀和加锁流程当出现多个线程同时竞争锁时,会进入到synchronizer.cpp#slow_enter方法
12345678910111213141516171819202122232425262728void ObjectSynchronizer::slow_enter(Handle o ...
好文收录 - 死磕Synchronized底层实现--轻量级锁
死磕Synchronized底层实现—轻量级锁
原文链接:死磕Synchronized底层实现—轻量级锁
本文为死磕Synchronized底层实现第三篇文章,内容为轻量级锁实现。
轻量级锁并不复杂,其中很多内容在偏向锁一文中已提及过,与本文内容会有部分重叠。
另外轻量级锁的背景和基本流程在概论中已有讲解。强烈建议在看过两篇文章的基础下阅读本文。
本系列文章将对HotSpot的synchronized锁实现进行全面分析,内容包括偏向锁、轻量级锁、重量级锁的加锁、解锁、锁升级流程的原理及源码分析,希望给在研究synchronized路上的同学一些帮助。主要包括以下几篇文章:
死磕Synchronized底层实现—概论
死磕Synchronized底层实现—偏向锁
死磕Synchronized底层实现—轻量级锁
死磕Synchronized底层实现—重量级锁
更多文章见个人博客:https://github.com/farmerjohngit/myblog
本文分为两个部分:
1.轻量级锁获取流程
2.轻量级锁释放流程
本人看的JVM版本是jdk8u,具体版本号以及代码可以在这里看到。
...
好文收录 - 死磕Synchronized底层实现--偏向锁
死磕Synchronized底层实现—偏向锁
原文链接:死磕Synchronized底层实现—偏向锁
本文为synchronized系列第二篇。主要内容为分析偏向锁的实现。
偏向锁的诞生背景和基本原理在上文中已经讲过了,强烈建议在有看过上篇文章的基础下阅读本文。
更多文章见个人博客:https://github.com/farmerjohngit/myblog
本系列文章将对HotSpot的synchronized锁实现进行全面分析,内容包括偏向锁、轻量级锁、重量级锁的加锁、解锁、锁升级流程的原理及源码分析,希望给在研究synchronized路上的同学一些帮助。主要包括以下几篇文章:
死磕Synchronized底层实现—概论
死磕Synchronized底层实现—偏向锁
死磕Synchronized底层实现—轻量级锁
死磕Synchronized底层实现—重量级锁
本文将分为几块内容:
1.偏向锁的入口
2.偏向锁的获取流程
3.偏向锁的撤销流程
4.偏向锁的释放流程
5.偏向锁的批量重偏向和批量撤销
本文分析的JVM版本是JVM8,具体版本号以及代码可以在这里看到。
偏向锁入口 ...
好文收录 - 死磕Synchronized底层实现--概论
死磕Synchronized底层实现—概论
原文链接:死磕Synchronized底层实现—概论
关于synchronized的底层实现,网上有很多文章了。但是很多文章要么作者根本没看代码,仅仅是根据网上其他文章总结、照搬而成,难免有些错误;要么很多点都是一笔带过,对于为什么这样实现没有一个说法,让像我这样的读者意犹未尽。
本系列文章将对HotSpot的synchronized锁实现进行全面分析,内容包括偏向锁、轻量级锁、重量级锁的加锁、解锁、锁升级流程的原理及源码分析,希望给在研究synchronized路上的同学一些帮助。主要包括以下几篇文章:
死磕Synchronized底层实现—概论
死磕Synchronized底层实现—偏向锁
死磕Synchronized底层实现—轻量级锁
死磕Synchronized底层实现—重量级锁
更多文章见个人博客:https://github.com/farmerjohngit/myblog
大概花费了两周的实现看代码(花费了这么久时间有些忏愧,主要是对C++、JVM底层机制、JVM调试以及汇编代码不太熟),将synchronized涉及到的代码 ...
变量的线程安全分析 —— 纠错与笔记
变量的线程安全分析 —— 纠错与笔记老师在本节的讲解中,存在较多错误的地方,在此进行纠错并记录。
成员变量的线程安全分析下面的例子在运行时确实会抛出 IndexOutOfBoundsException,但原因并不是老师所说的:线程 1 还未执行完 method2() 将元素添加到 list 中,线程 2 就执行了 method3() 尝试从空的 list 中移除元素。
错误很明显,不论线程切换导致指令如何交错,至少单个线程内的指令是顺序执行的,这意味着,如果线程 2 执行到了 method3(),此前就一定已经执行完了 method2()。
因此,无论线程 1 是否执行了 method2(),至少能保证线程 2 的 method2() 已执行,list 中至少放入了一个元素,从而 method3() 不可能是从空的 list 中移除元素。
12345678910111213141516171819202122232425262728293031public class TestThreadSafe { static final int THREAD_NUMBER = 2 ...
多级缓存 - Canal 与 JVM 本地缓存的矛盾
多级缓存 - Canal 与 JVM 本地缓存的矛盾问题背景
Canal Server 通过伪装为 MySQL Slave 可以监听到 MySQL Master 库日志 binary log 的变化,对 binary log 变化进行解析,Canal Server 就能知道 MySQL Master 中具体执行了什么操作,接着就可以将解析后的消息转发给 Canal Client。
在如上多级缓存的架构图中,Canal Server 有两个 Canal Client,就是商品服务的两个 Tomcat 实例。当 MySQL Master 执行了写操作后,Canal Server 监听并解析后的消息,是广播给每个 Canal Client,还是仅仅发送给其中一个呢?
实验发现,Canal Server 是以轮询的方式,将解析后的消息发送给其中一个 Canal Client 的。
其中一个 Canal Client 接收到消息后,它的消费逻辑是:
同步本地 Caffeine 缓存
同步 Redis 缓存
同步 Redis 缓存没什么问题,但是同步本地 Caffeine 缓存其实是有些问题的 ...
好文收录 - 如何理解 TCC 分布式事务
好文收录 - 如何理解 TCC 分布式事务
如何理解 TCC 分布式事务? - bytefox 的回答 - 知乎
一个TCC事务框架需要解决的当然是分布式事务的管理。关于TCC事务机制的介绍,可以参考TCC事务机制简介。
TCC事务模型虽然说起来简单,然而要基于TCC实现一个通用的分布式事务框架,却比它看上去要复杂的多,不只是简单的调用一下Confirm/Cancel业务就可以了的。
下文将以Spring容器为例,试图分析一下,实现一个通用的TCC分布式事务框架需要注意的一些问题。
一、TCC全局事务必须基于RM本地事务来实现全局事务TCC服务是由Try/Confirm/Cancel业务构成的,其Try/Confirm/Cancel业务在执行时,会访问资源管理器(Resource Manager,下文简称RM)来存取数据。这些存取操作,必须要参与RM本地事务,以使其更改的数据要么全部commit,要么全部rollback。
这一点不难理解,考虑一下如下场景:
假设图中的服务B没有基于RM本地事务(以RDBS为例,可通过设置auto-commit为true来模拟),那么一旦[B:Tr ...
Sentinel 实验
Sentinel 实验通过观察 Sentinel 的日志输出,大概能看懂 Sentinel 的工作模式。
1java -Dserver.port=8090 -Dlogging.level.org.springframework.web=TRACE -jar `sentinel`-dashboard-1.8.1.jar
Sentinel 控制台和 Sentinel 客户端都启动以后,双方并不会直接就互相感知到。只有等到 Sentinel 客户端访问了端点后,Sentinel 客户端才会开始向 Sentinel 控制台发送心跳,此时双方才互相感知到。随后,Sentinel 控制台会定期向 Sentinel 客户端发送请求,获取客户端的运行信息,从而实现监控。
当在 Sentinel 控制台为客户端的相关资源配置规则时,规则信息会发送到对应的 Sentinel 客户端。默认情况下,Sentinel 客户端接收到配置规则信息以后,是将其存储在内存中。因此,如果 Sentinel 客户端重启了,那么所有的配置规则都将丢失。即使 Sentinel 客户端重新连接,也无法从 Sentinel 控制台 ...