【SQL】InnoDB的意向锁

InnoDB 中的意向锁(Intention Locks)是一种表级锁,用于表示事务打算对表中的某些行加锁。意向锁不会阻塞其他事务的操作,但在检测表锁冲突时会被考虑。

意向锁有两种类型:

  1. 意向共享锁(Intention Shared Lock, IS):事务打算获取表中某些行的共享锁。
  2. 意向排他锁(Intention Exclusive Lock, IX):事务打算获取表中某些行的排他锁。

意向锁的作用

意向锁的主要作用是加速锁检查。它们允许 InnoDB 在检测锁冲突时快速确定一个表是否可以安全地加锁,而无需逐行检查。

意向锁的工作原理

当一个事务试图在某些行上获取共享锁或排他锁时,它首先在表上获取相应的意向锁。如果两个事务在同一张表上获取了兼容的意向锁,它们可以在表的不同行上分别加锁。

例如:

  • 如果事务 A 对某行加共享锁,那么它首先需要在表上加意向共享锁(IS)。
  • 如果事务 B 对另一行加排他锁,那么它首先需要在表上加意向排他锁(IX)。

锁兼容性

ISIXSX
ISYesYesYesNo
IXYesYesNoNo
SYesNoYesNo
XNoNoNoNo

示例

假设有一个 employees 表:

CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    salary DECIMAL(10, 2)
) ENGINE=InnoDB;
使用意向共享锁
BEGIN;
SELECT * FROM employees WHERE salary > 4000 LOCK IN SHARE MODE;

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

使用意向排他锁
BEGIN;
UPDATE employees SET salary = salary + 1000 WHERE id = 1;

该语句在 id = 1 的记录上加了排他锁 (X 锁),同时在表上加了意向排他锁 (IX 锁)。

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 InnoDBIntentionLockExample {
    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 salary > 4000 LOCK IN SHARE MODE";
            try (PreparedStatement pstmt = conn.prepareStatement(query);
                 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 来执行一个带有意向共享锁的查询。首先,设置连接为手动提交模式,然后执行一个带有 LOCK IN SHARE MODE 的查询以加锁。最后,提交事务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值