【SQL】InnoDB中的行锁

InnoDB 里的行锁机制主要通过索引来实现,而不是直接对表中的记录加锁。具体来说,InnoDB 使用以下几种锁定机制来实现行锁:

  1. 记录锁 (Record Lock):锁定单个索引记录。
  2. 间隙锁 (Gap Lock):锁定索引记录之间的间隙,防止其他事务在该间隙插入新记录。
  3. 临键锁 (Next-Key Lock):结合记录锁和间隙锁,锁定一个索引记录以及其前面的间隙。

行锁的实现

InnoDB 的行锁是通过对索引项加锁来实现的,这意味着只有通过索引访问数据,InnoDB 才能使用行级锁定。如果一个 SQL 语句不使用索引,InnoDB 会退化为表锁。

锁的类型

  • 共享锁 (S 锁):允许事务读取一条记录,但不允许修改。
  • 排他锁 (X 锁):不允许其他事务读取或修改一条记录。

示例

假设有一个 employees 表:

CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    salary DECIMAL(10, 2)
) ENGINE=InnoDB;
使用 FOR UPDATE 加锁
BEGIN;
SELECT * FROM employees WHERE id = 1 FOR UPDATE;

该语句在 id = 1 的记录上加了一个排他锁 (X 锁)。由于 id 是主键,这是一个记录锁。

插入操作导致的间隙锁
BEGIN;
INSERT INTO employees (id, name, salary) VALUES (5, 'Alice', 5000);

插入操作会导致在相应索引上的间隙锁,以防止其他事务在相同间隙中插入记录。

使用共享锁
BEGIN;
SELECT * FROM employees WHERE salary > 4000 LOCK IN SHARE MODE;

该语句在符合条件的记录上加了共享锁 (S 锁),同时会在表上加意向共享锁 (IS 锁)。

Java 代码示例

假设你想通过 Java 代码来执行这些操作,可以使用 JDBC:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class InnoDBLockExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/yourdatabase";
        String user = "yourusername";
        String password = "yourpassword";

        try (Connection conn = DriverManager.getConnection(url, user, password)) {
            // 开始事务
            conn.setAutoCommit(false);

            // 加锁查询
            String query = "SELECT * FROM employees WHERE id = ? FOR UPDATE";
            try (PreparedStatement pstmt = conn.prepareStatement(query)) {
                pstmt.setInt(1, 1);
                try (ResultSet rs = pstmt.executeQuery()) {
                    while (rs.next()) {
                        System.out.println("ID: " + rs.getInt("id") + ", Name: " + rs.getString("name"));
                    }
                }
            }

            // 提交事务
            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

该 Java 代码示例演示了如何使用 JDBC 来执行一个带有行锁的查询。首先,设置连接为手动提交模式,然后执行一个带有 FOR UPDATE 的查询以加锁。最后,提交事务。

相关推荐

  1. 【SQL】InnoDB

    2024-07-11 10:38:01       21 阅读
  2. MySQL,,排它,共享

    2024-07-11 10:38:01       52 阅读
  3. Mysql正经、间隙和临键

    2024-07-11 10:38:01       57 阅读
  4. 浅谈InoDB

    2024-07-11 10:38:01       25 阅读
  5. MySQLFor Update

    2024-07-11 10:38:01       34 阅读
  6. 并发

    2024-07-11 10:38:01       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 10:38:01       53 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 10:38:01       56 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 10:38:01       46 阅读
  4. Python语言-面向对象

    2024-07-11 10:38:01       57 阅读

热门阅读

  1. 编程什么好用:深入剖析编程工具的选择与运用

    2024-07-11 10:38:01       21 阅读
  2. C++引用和指针的区别

    2024-07-11 10:38:01       19 阅读
  3. 3.数组基础

    2024-07-11 10:38:01       16 阅读
  4. Docker 日志丢失 - 解决方案

    2024-07-11 10:38:01       17 阅读
  5. 3D Web开发新篇章:threelab探索之旅

    2024-07-11 10:38:01       18 阅读
  6. 外科休克病人的护理

    2024-07-11 10:38:01       16 阅读