/images/logo.jpg

[MySQL] 2. Lock Mechanism Execution Analysis

[MySQL] 2. Lock Mechanism Execution Analysis

1. Introduction

In high-concurrency environments, database locking mechanisms are crucial for ensuring data consistency and integrity. MySQL, as a widely-used relational database, provides various lock types and mechanisms to manage concurrent access. However, improper use of locks may lead to performance bottlenecks, deadlocks, and other issues that affect system stability and response time.

  • Lock Definition: A lock is a mechanism used to control access to shared resources, preventing multiple transactions from modifying the same data simultaneously, thereby ensuring data consistency and integrity.
  • Lock Types:
    • Table-level Lock: Locks the entire table.
    • Shared Lock (S Lock): Allows multiple transactions to read data simultaneously but prevents modification.
    • Exclusive Lock (X Lock): Allows one transaction to modify data while preventing other transactions from reading or modifying.
    • Intention Locks (IS and IX Locks): Used at the table level to indicate that a transaction intends to acquire locks at the row level.
    • Auto-increment Lock (AUTO-INC Lock): Used to handle concurrent inserts on auto-increment columns, preventing conflicts.
    • Gap Lock: Locks the gaps between index records to prevent phantom reads.
    • Next-Key Lock: Combines record locks and gap locks, locking index records and the gaps before them.
    • Record Lock: Locks specific index records.
    • Row-level Lock: Locks specific rows.
    • Optimistic Lock: Implemented through version numbers or timestamps, suitable for read-heavy scenarios.
    • Pessimistic Lock: Implemented through explicit locking, suitable for write-heavy scenarios.
  • Deadlock: Multiple transactions wait for each other to release locks, resulting in inability to continue execution.
  • Lock Compatibility: Compatibility rules exist between different types of locks, determining which locks can coexist.
  • Lock Granularity: The scope of locked resources; finer granularity provides higher system concurrency but increases management overhead.

3. MySQL Lock Introduction

3.1 Basic Commands

  • Create test table
1
2
3
4
5
6
7
8
9
-- auto-generated definition
create table example_single_pk
(
    id      bigint                              not null comment 'id'
        primary key,
    created timestamp default CURRENT_TIMESTAMP not null comment 'create time',
    updated timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'update time'
)
    comment 'example_single_pk' charset = utf8mb4;
  • Execute commands
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
SELECT id, created, updated FROM example_single_pk;

INSERT INTO example_single_pk (id) VALUES (1);

SELECT id, created, updated FROM example_single_pk;

UPDATE example_single_pk SET id = 6 WHERE id = 1;

SELECT id, created, updated FROM example_single_pk;

DELETE FROM example_single_pk WHERE id = 1 or id = 6;

SELECT id, created, updated FROM example_single_pk;
  • Results
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
mysql> SELECT id, created, updated FROM example_single_pk;
Empty set (0.00 sec)

mysql>
mysql> INSERT INTO example_single_pk (id) VALUES (1);
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> SELECT id, created, updated FROM example_single_pk;
+----+---------------------+---------------------+
| id | created             | updated             |
+----+---------------------+---------------------+
|  1 | 2025-09-27 11:14:40 | 2025-09-27 11:14:40 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)

mysql>
mysql> UPDATE example_single_pk SET id = 6 WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>
mysql> SELECT id, created, updated FROM example_single_pk;
+----+---------------------+---------------------+
| id | created             | updated             |
+----+---------------------+---------------------+
|  6 | 2025-09-27 11:14:40 | 2025-09-27 11:14:40 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)

mysql>
mysql> DELETE FROM example_single_pk WHERE id = 1 or id = 6;
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> SELECT id, created, updated FROM example_single_pk;
Empty set (0.00 sec)

3.2 Classification by Granularity

3.2.1 Table-level Lock - READ

3.2.1.1 Locking
1
2
mysql> LOCK TABLES example_single_pk READ;
Query OK, 0 rows affected (0.00 sec)

/images/12.%20mysql%20lock/1.1%20lock%20tables%20read.png

[MySQL] 2. 锁机制执行分析

[MySQL] 2. 锁机制执行分析

1. 引言

  • 在高并发环境下,数据库锁机制是确保数据一致性和完整性的关键手段。MySQL作为广泛使用的关系型数据库,提供了多种锁类型和机制来管理并发访问。然而,锁的使用不当可能导致性能瓶颈、死锁等问题,影响系统的稳定性和响应速度。

2. 锁相关基本概念

  • 锁的定义:锁是一种机制,用于控制对共享资源的访问,防止多个事务同时修改同一数据,确保数据的一致性和完整性。
  • 锁的类型
    • 表级锁:锁定整个表。
    • 共享锁(S锁):允许多个事务同时读取数据,但不允许修改。
    • 排他锁(X锁):允许一个事务修改数据,其他事务既不能读取也不能修改。
    • 意向锁(IS锁和IX锁):用于表级别,表示事务打算在行级别上加锁。
    • 自增锁(AUTO-INC锁):用于处理自增列的并发插入,防止冲突。
    • 间隙锁(Gap Lock):锁定索引记录之间的间隙,防止幻读。
    • 临键锁(Next-Key Lock):结合了记录锁和间隙锁,锁定索引记录及其前面的间隙。
    • 记录锁(Record Lock):锁定具体的索引记录。
    • 行级锁:锁定具体的行。
    • 乐观锁:通过版本号或时间戳实现,适用于读多写少的场景。
    • 悲观锁:通过显式加锁实现,适用于写多读少的场景。
  • 死锁:多个事务互相等待对方释放锁,导致无法继续执行。
  • 锁的兼容性:不同类型的锁之间存在兼容性规则,决定了哪些锁可以同时存在。
  • 锁的粒度:锁定资源的范围,粒度越细,系统并发性越高,但管理开销也越大。

3. MySQL锁介绍

3.1 基本命令

  • 创建测试表
1
2
3
4
5
6
7
8
9
-- auto-generated definition
create table example_single_pk
(
    id      bigint                              not null comment 'id'
        primary key,
    created timestamp default CURRENT_TIMESTAMP not null comment 'create time',
    updated timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'update time'
)
    comment 'example_single_pk' charset = utf8mb4;
  • 执行命令
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
SELECT id, created, updated FROM example_single_pk;

INSERT INTO example_single_pk (id) VALUES (1);

SELECT id, created, updated FROM example_single_pk;

UPDATE example_single_pk SET id = 6 WHERE id = 1;

SELECT id, created, updated FROM example_single_pk;

DELETE FROM example_single_pk WHERE id = 1 or id = 6;

SELECT id, created, updated FROM example_single_pk;
  • 结果
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
mysql> SELECT id, created, updated FROM example_single_pk;
Empty set (0.00 sec)

mysql> 
mysql> INSERT INTO example_single_pk (id) VALUES (1);
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> SELECT id, created, updated FROM example_single_pk;
+----+---------------------+---------------------+
| id | created             | updated             |
+----+---------------------+---------------------+
|  1 | 2025-09-27 11:14:40 | 2025-09-27 11:14:40 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)

mysql> 
mysql> UPDATE example_single_pk SET id = 6 WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> 
mysql> SELECT id, created, updated FROM example_single_pk;
+----+---------------------+---------------------+
| id | created             | updated             |
+----+---------------------+---------------------+
|  6 | 2025-09-27 11:14:40 | 2025-09-27 11:14:40 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)

mysql> 
mysql> DELETE FROM example_single_pk WHERE id = 1 or id = 6;
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> SELECT id, created, updated FROM example_single_pk;
Empty set (0.00 sec)

3.2 按粒度分

3.2.1 表级锁 - READ

3.2.1.1 加锁
1
2
mysql> LOCK TABLES example_single_pk READ;
Query OK, 0 rows affected (0.00 sec)

/images/12.%20mysql%20lock/1.1%20lock%20tables%20read.png

[Github] 4. Value-Checker-Java: Customizable AOP Validation Framework

[Github] 4. Value-Checker-Java: Customizable AOP Validation Framework

1. Introduction

Value-Checker-Java is essentially a customizable AOP pointcut framework. It allows developers to insert custom validation logic before method execution, and this validation logic can be arbitrarily complex business rules.

However, if it merely provides an AOP pointcut, that wouldn’t be very meaningful. The core value of Value-Checker-Java lies in its thread-safe context management mechanism. Without this context management, data queried in the first validator cannot be used in subsequent validators, forcing each validator to re-query data, which defeats the purpose of validation chains.

[Github] 4. Value-Checker-Java:可自定义的AOP验证框架

[Github] 4. Value-Checker-Java:可自定义的AOP验证框架

1.1 引言

Value-Checker-Java本质上是一个可自定义的AOP切入点框架。它允许开发者在方法执行前插入自定义的验证逻辑,而这些验证逻辑可以是任意复杂的业务规则。

但是,如果仅仅是提供一个AOP切入点,那意义并不大。Value-Checker-Java的核心价值在于它提供了线程安全的上下文管理机制。如果没有这个上下文管理,在第一个验证器中查询的数据就无法在后续的验证器中使用,每个验证器都必须重新查询数据,这样就失去了验证链的意义。

正是因为有了ValueCheckerReentrantThreadLocal这个线程安全的上下文管理器,多个验证器才能够共享数据,形成真正有意义的验证链条。

1.2 Github

value-checker-java-8

value-checker-java-17

2. 基本使用

2.1 验证器配置

1
2
3
4
5
6
7
8
9
// 来自TargetService.java
@ValueCheckers(checkers = {
    @ValueCheckers.ValueChecker(method = "verify", keys = {"#id", "#name"}, handler = SampleCheckerHandlerImpl.class),
    @ValueCheckers.ValueChecker(method = "verify", keys = "#id", handler = SampleCheckerHandlerImpl.class),
    @ValueCheckers.ValueChecker(method = "verify", keys = "#name", handler = SampleCheckerHandlerImpl.class)
})
public void checker(Long id, String name) {
    // 会按顺序执行3个验证器
}

2.2 验证器实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 来自SampleCheckerHandlerImpl.java
@Service
public class SampleCheckerHandlerImpl implements IValueCheckerHandler {
    public static final Long CORRECT_ID = 2L;
    public static final String CORRECT_NAME = "correctName";

    public void verify(Long id, String name) {
        if (!CORRECT_ID.equals(id) || !CORRECT_NAME.equals(name)) {
            throw new ValueIllegalException("error");
        }
    }

    public void verify(Long id) {
        if (!CORRECT_ID.equals(id)) {
            throw new ValueIllegalException("error");
        }
    }

    public void verify(String name) {
        if (!CORRECT_NAME.equals(name)) {
            throw new ValueIllegalException("error");
        }
    }
}

2.3 关键技术实现

2.3.1 注解设计

@ValueCheckers采用了嵌套注解的设计模式:

[Github] 3. Basic-Check: Validation Framework

[Github] 3. Basic-Check: Validation Framework

Introduction

Parameter validation is a common and crucial requirement in daily Java development. Traditional parameter validation typically requires writing extensive if-else conditional code in each method, which is not only redundant and tedious but also prone to omissions. Basic-Check-Java was born to solve this pain point as a lightweight parameter validation framework.

This article will provide an in-depth introduction to Basic-Check-Java’s design philosophy, core features, and practical applications, helping developers quickly master this practical tool.

[Github] 3. Basic-Check:参数验证框架

[Github] 3. Basic-Check:参数验证框架

引言

在日常的Java开发中,方法参数验证是一个常见且重要的需求。传统的参数验证通常需要在每个方法中编写大量的if-else判断代码,不仅冗余繁琐,还容易遗漏。Basic-Check-Java正是为了解决这一痛点而诞生的轻量级参数验证框架。

本文将深入介绍Basic-Check-Java的设计理念、核心特性以及实际应用,帮助开发者快速掌握这个实用的工具。

Github

basic-check-java-8

basic-check-java-17

设计理念与核心特性

设计理念

Basic-Check-Java基于以下核心理念设计:

  1. 简洁性:通过注解声明式编程,减少样板代码
  2. 灵活性:支持多种返回策略,适应不同业务场景
  3. 无侵入性:基于AOP实现,对业务代码零侵入
  4. 可扩展性:支持自定义验证规则和处理逻辑

核心特性

1. 丰富的参数验证注解

Basic-Check-Java提供了六种常用的参数验证注解:

  • @CheckNull:验证参数不为null
  • @CheckString:验证字符串参数非空白
  • @CheckLong:验证Long类型参数大于-1
  • @CheckCollection:验证集合类型参数非空
  • @CheckMap:验证Map类型参数非空
  • @CheckObject:使用Bean Validation验证对象参数

2. 灵活的返回策略

通过@BasicCheck注解的returnType属性,支持三种验证失败时的处理策略:

  • EXCEPTION(默认):抛出IllegalArgumentException异常
  • EMPTY:根据方法返回类型自动返回空值(空集合、空Map、Optional.empty()等)
  • NULL:直接返回null

3. 基于Spring AOP的无侵入式实现

框架采用AspectJ注解和Spring AOP技术,通过切面编程在方法执行前进行参数验证,对业务代码完全无侵入。

技术架构深入分析

核心架构图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@BasicCheck注解方法
NotNullAndPositiveAspect切面拦截
遍历方法参数及其注解
根据注解类型执行相应验证逻辑
验证失败 → 根据returnType返回相应结果
验证成功 → 继续执行原方法

关键技术实现

1. 注解设计

@BasicCheck为例,展示了优雅的注解设计: