MVCC、锁

1. mysql 锁

1事务A进行创建表

sql 复制代码
-- ------------------------------------------------------------------------------1.创建表
-- 创建测试表
CREATE TABLE IF NOT EXISTS test_lock (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ------------------------------------------------------------------------------2.插入数据
-- 插入初始数据
INSERT INTO test_lock (name, age) VALUES ('Alice', 20), ('Bob', 25), ('Charlie', 30);


-- ----------------------------------------------------------------------------3.隔离级别
-- 1. 查看当前隔离级别
SELECT @@transaction_isolation; 
-- (旧版本MySQL可能是 @@tx_isolation)
-- 2. 设置当前会话的隔离级别 (四种任选其一)
-- 选项 A: 读未提交
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 选项 B: 读已提交 (推荐用于高并发写场景)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 选项 C: 可重复读 (MySQL 默认,推荐用于强一致性场景)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 选项 D: 串行化 (性能极差,仅测试用)
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- 3. 再次确认是否设置成功
SELECT @@transaction_isolation;

-- -------------------------------------------------------------------------------------4.窗口A,隐式枷锁
-- 设置隔离级别为 RR
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
-- 执行更新,此时自动给 id=1 的行加了排他锁
UPDATE test_lock SET age = 21 WHERE id = 1; 

COMMIT

-- ⚠️ 注意:此时不要执行 COMMIT 或 ROLLBACK,让事务挂着!

--  ---------------------------------------------------------------------------------------5.显式加锁

START TRANSACTION;
-- 这行代码会立即给 id=1 加上排他锁,即使你只是读取
SELECT * FROM test_lock WHERE id = 1 FOR UPDATE;
-- 此时其他事务无法更新或删除 id=1
COMMIT

-- ---------------------------------------------------------------------6.显式加锁
START TRANSACTION;
-- MySQL 8.0+ 写法
SELECT * FROM test_lock WHERE id = 1 FOR SHARE;
-- MySQL 5.7 及以前写法
-- SELECT * FROM test_lock WHERE id = 1 LOCK IN SHARE MODE;

2.事务B:尝试在事务A持有锁的情况下,查询,验证锁

sql 复制代码
-- -----------------------------------------------------1. 事务B的查询
-- 事务B
START TRANSACTION;

-- 尝试更新同一行,这里会被阻塞(卡住),直到窗口1提交或回滚
UPDATE test_lock SET age = 22 WHERE id = 1;
COMMIT

-- 如果卡住了,说明锁生效了!




-- ----------------------------------------------------2. 基础锁的查询
SELECT
  OBJECT_NAME,
  LOCK_TYPE,
  LOCK_MODE,
  LOCK_STATUS,
  LOCK_DATA,
  THREAD_ID
FROM performance_schema.data_locks;

得到结果

2.RR RC级别下的读取结果不一致

3.mysql中的事务自动提交

📌 先搞懂 MySQL 的「自动提交」规则(关键)

MySQL 默认开启 autocommit=ON(自动提交),核心规则:

  1. 无显式事务时 :每一条 DML 语句(INSERT/UPDATE/DELETE)都会被当成独立事务 ,执行后立即自动提交 ,无需手动写 COMMIT。
  2. 显式事务时 :只有写了 START TRANSACTION/BEGIN,才会关闭本次会话的自动提交,直到执行 COMMIT/ROLLBACK 后恢复。
相关推荐
for_ever_love__8 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
Sayai11 小时前
DataX 离线数据同步实战:Elasticsearch 数据批量导出 MySQL(作业配置、并发调优与定时同步平台化设计)
大数据·mysql·elasticsearch·datax·数据同步
颜酱12 小时前
一栋商业大厦,讲清 InnoDB 的表空间、段、区和页
后端·mysql
PC2005-cloud14 小时前
Mysql学习笔记:InnoDB Cluster 集群从零搭建实战,基于 Docker 实现高可用读写分离架构
笔记·学习·mysql
这个DBA有点耶15 小时前
分布式事务深度:TCC空回滚、悬挂与Saga补偿风暴的根因与解法
数据库·mysql·代码规范
QEasycloud15 小时前
BOM接口抛转失败钉钉通知策略实战教程:MySQL异常日志到钉钉消息的端到端配置
android·mysql·钉钉
又尔D.15 小时前
MySQL下载安装
数据库·mysql
夜雪一千15 小时前
MySQL 删除 JSON 类型的数据实战
mysql·adb·json
iCxhust17 小时前
51单片机电力载波应用开发(九)51产品化
c语言·数据库·嵌入式硬件·mysql·51单片机·软件工程·c51
tryxr17 小时前
如何分析一个慢sql
数据库·sql·mysql·慢sql