当前位置: 首页 > news >正文

网页设计与制作个人网站模板做票据业务的p2p网站

网页设计与制作个人网站模板,做票据业务的p2p网站,深圳工程建设有限公司,wordpress文章添加阅读全文MySQL 锁机制是保证数据库并发控制的核心手段,用于解决多用户同时操作数据库时可能出现的脏读、不可重复读、幻读等问题。合理使用锁可以平衡数据库的并发性能与数据一致性。一、锁的基本概念与分类MySQL 锁根据不同维度可分为多种类型:按锁的粒度划分&a…

MySQL 锁机制是保证数据库并发控制的核心手段,用于解决多用户同时操作数据库时可能出现的脏读、不可重复读、幻读等问题。合理使用锁可以平衡数据库的并发性能与数据一致性。

一、锁的基本概念与分类

MySQL 锁根据不同维度可分为多种类型:

  • 按锁的粒度划分行级锁、表级锁、页级锁
  • 按锁的模式划分共享锁(S 锁)、排他锁(X 锁)
  • 按锁的使用方式划分自动锁、显式锁
  • 特殊锁类型意向锁、间隙锁、临键锁、记录锁等

不同的存储引擎支持的锁机制不同,其中 InnoDB 是 MySQL 中唯一支持行级锁的存储引擎,也是目前最常用的存储引擎。

二、表级锁

表级锁是粒度最大的一种锁,对整张表加锁,实现简单,开销小,加锁快,但并发度低。

1. 表级锁的类型

(1)表共享读锁(Table Read Lock)
  • 多个会话可以同时获取表的读锁
  • 持有读锁的会话只能读表,不能写表
  • 其他会话不能获取写锁,直到所有读锁释放
(2)表独占写锁(Table Write Lock)
  • 只有一个会话可以获取表的写锁
  • 持有写锁的会话可以读写表
  • 其他会话不能获取读锁和写锁,直到写锁释放

2. 表级锁示例

使用 LOCK TABLES 命令手动获取表级锁:

-- 会话1:获取表的读锁
LOCK TABLES users READ;-- 可以读取数据
SELECT * FROM users WHERE id = 1;-- 不能写入数据,会报错
UPDATE users SET name = 'test' WHERE id = 1;-- 会话2:尝试获取写锁会被阻塞,直到会话1释放锁
LOCK TABLES users WRITE;-- 释放锁
UNLOCK TABLES;

3. 表级锁的适用场景

表级锁适合以下场景:

  • 全表数据迁移或批量更新
  • 读写比例严重失衡,读远多于写的场景
  • MyISAM 存储引擎(只支持表级锁)

三、行级锁

行级锁是粒度最小的锁,只对指定的记录加锁,并发度高,但实现复杂,开销大,加锁慢。InnoDB 支持行级锁,这也是其广泛应用的重要原因。

1. 行级锁的类型

(1)共享锁(S 锁,Shared Locks)
  • 允许事务读取一行数据
  • 多个事务可以同时对同一行加 S 锁
  • 加了 S 锁的行,不能被加 X 锁,直到所有 S 锁释放
(2)排他锁(X 锁,Exclusive Locks)
  • 允许事务更新或删除一行数据
  • 同一行只能有一个 X 锁
  • 加了 X 锁的行,不能被加 S 锁或 X 锁,直到 X 锁释放

2. 行级锁示例

InnoDB 默认在 SELECT ... FOR UPDATE 时加排他锁

在 SELECT ... LOCK IN SHARE MODE 时加共享锁:

共享锁示例:

-- 会话1:获取行的共享锁
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;-- 会话2:可以获取同一行的共享锁
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;-- 会话2:尝试更新会被阻塞,因为会话1持有S锁
UPDATE users SET name = 'test' WHERE id = 1;-- 会话1:释放锁(提交事务)
COMMIT;-- 会话2:此时更新操作会执行

排他锁示例:

-- 会话1:获取行的排他锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;-- 会话2:尝试获取共享锁会被阻塞
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;-- 会话2:尝试获取排他锁会被阻塞
SELECT * FROM users WHERE id = 1 FOR UPDATE;-- 会话1:释放锁
COMMIT;-- 会话2:此时查询会执行

四、意向锁

意向锁(Intention Locks)是表级锁,用于指示事务稍后会对表中的行加哪种类型的锁(共享锁或排他锁),是 InnoDB 为了支持多粒度锁而引入的。

1. 意向锁的类型

  • 意向共享锁(IS 锁)事务意图在表中的某些行上加共享锁
  • 意向排他锁(IX 锁)事务意图在表中的某些行上加排他锁

2. 意向锁的兼容性

锁类型共享锁 (S)排他锁 (X)意向共享锁 (IS)意向排他锁 (IX)
共享锁 (S)兼容冲突兼容冲突
排他锁 (X)冲突冲突冲突冲突
意向共享锁 (IS)兼容冲突兼容兼容
意向排他锁 (IX)冲突冲突兼容兼容

3. 意向锁示例

-- 当执行以下语句时,InnoDB会自动先加意向共享锁
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;-- 当执行以下语句时,InnoDB会自动先加意向排他锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;

五、记录锁、间隙锁与临键锁

这三种锁是 InnoDB 在处理行级锁时使用的具体锁类型,尤其在使用索引时发挥作用。

1. 记录锁(Record Locks)

记录锁是对索引记录加的锁,锁定单行记录。

-- 对id=1的记录加排他锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;

2. 间隙锁(Gap Locks)

间隙锁锁定索引记录之间的间隙,或索引记录之前 / 之后的间隙,防止其他事务在间隙中插入数据,用于解决幻读问题。

-- users表中存在id=1,3,5的记录
-- 会话1:锁定id在1到5之间的间隙
SELECT * FROM users WHERE id BETWEEN 1 AND 5 FOR UPDATE;-- 会话2:尝试在间隙中插入数据会被阻塞
INSERT INTO users (id, name) VALUES (2, 'test');
INSERT INTO users (id, name) VALUES (4, 'test');

3. 临键锁(Next-Key Locks)

临键锁是记录锁和间隙锁的组合,锁定索引记录及其前面的间隙,是 InnoDB 默认的行级锁类型(当使用范围条件而非相等条件检索数据时)。

-- users表中存在id=1,3,5的记录
-- 会话1:使用临键锁
SELECT * FROM users WHERE id > 2 AND id < 5 FOR UPDATE;-- 这会锁定id=3的记录,以及(2,3)和(3,5)的间隙
-- 会话2:以下操作会被阻塞
INSERT INTO users (id, name) VALUES (2, 'test');  -- 插入到(2,3)间隙
INSERT INTO users (id, name) VALUES (4, 'test');  -- 插入到(3,5)间隙
UPDATE users SET name = 'test' WHERE id = 3;      -- 更新id=3的记录

六、自增锁

自增锁(Auto-inc Locks)是一种特殊的表级锁,用于事务插入带有自增列(AUTO_INCREMENT)的表时使用。

自增锁示例

-- 创建带有自增列的表
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(10)
);-- 会话1:获取自增锁
INSERT INTO test (name) VALUES ('a');-- 会话2:插入会被阻塞,直到会话1释放自增锁
INSERT INTO test (name) VALUES ('b');-- 会话1:提交事务,释放自增锁
COMMIT;

在 MySQL 8.0 中,默认使用 innodb_autoinc_lock_mode = 2(连续模式),优化了自增锁的性能,对于简单插入语句不会使用表级自增锁,而是通过轻量级锁实现。

七、元数据锁

元数据锁(MDL,Metadata Locks)用于保护表的元数据信息,在事务中访问表时自动获取,确保读写一致性。

MDL 锁示例

-- 会话1:开始事务,访问表,获取MDL读锁
START TRANSACTION;
SELECT * FROM users LIMIT 1;-- 会话2:尝试修改表结构会被阻塞,因为会话1持有MDL读锁
ALTER TABLE users ADD COLUMN age INT;-- 会话1:提交事务,释放MDL读锁
COMMIT;-- 会话2:此时ALTER操作会执行

长时间运行的事务会持有 MDL 锁,可能导致表结构修改操作阻塞,在实际应用中应避免长事务。

八、数据库锁的常用实战场景

1. 秒杀 / 高并发库存扣减

场景商品秒杀时,多个用户同时抢购同一商品,需确保库存不超卖。
锁策略

  • 使用行级锁(如 MySQL 的FOR UPDATE)锁定特定商品的库存记录
  • 示例:
    BEGIN;
    -- 锁定id=1001的商品记录
    SELECT stock FROM products WHERE id=1001 FOR UPDATE;
    -- 检查库存并扣减
    UPDATE products SET stock=stock-1 WHERE id=1001 AND stock>0;
    COMMIT;
    
  • 避免使用表锁,防止并发性能过低

2. 订单状态更新

场景订单可能被多个进程同时操作(支付、取消、超时等),需保证状态转换的一致性。
锁策略

  • 采用悲观锁确保状态更新的原子性
  • 或使用乐观锁(版本号机制)实现无锁并发控制:
    -- 乐观锁实现:只有版本号匹配时才更新
    UPDATE orders 
    SET status='paid', version=version+1 
    WHERE order_id='O12345' AND version=3;
    

3. 分布式事务数据一致性

场景跨库事务中(如订单创建同时扣减库存),需保证多库操作的一致性。
锁策略

  • 使用分布式锁(如基于 Redis 或 ZooKeeper 实现)
  • 结合本地数据库锁,形成 "分布式锁 + 本地锁" 的双层锁机制
  • 示例:用 Redis 的SETNX获取分布式锁,再操作本地数据库

4. 数据迁移 / 批量更新

场景后台任务批量更新大量数据时,需避免与正常业务操作冲突。
锁策略

  • 使用表级锁(如 MySQL 的LOCK TABLES)或分区锁
  • 对数据分片处理,使用范围锁减少锁定范围:
    -- 锁定id在1000-2000范围的记录
    SELECT * FROM user_data WHERE id BETWEEN 1000 AND 2000 FOR UPDATE;
    

5. 防止重复提交

场景用户重复点击提交按钮,导致重复创建数据(如重复订单)。
锁策略

  • 基于唯一索引的隐式锁:在唯一字段上创建唯一索引
  • 结合分布式锁,以业务唯一标识作为锁键:
    // 伪代码:使用订单号作为锁键
    if (redisLock.tryLock(orderNo, 3000)) {try {// 检查订单是否已存在,不存在则创建} finally {redisLock.unlock();}
    }
    

6. 热点数据保护

场景热门商品、首页推荐等高频访问的数据,避免并发更新导致的数据不一致。
锁策略

  • 采用读写锁(如 PostgreSQL 的SELECT ... FOR SHARE
  • 读多写少场景:读操作加共享锁,写操作加排他锁
  • 示例:
    -- 读操作加共享锁
    SELECT * FROM hot_products WHERE id=5 FOR SHARE;-- 写操作加排他锁
    SELECT * FROM hot_products WHERE id=5 FOR UPDATE;
    

7. 定时任务并发控制

场景多个服务器节点的定时任务同时执行,导致重复处理。
锁策略

  • 使用分布式锁控制任务执行权
  • 结合过期时间防止锁永久占用:
    // 伪代码:定时任务获取锁
    if (distributedLock.tryLock("daily_task", 60000)) {try {// 执行定时任务} finally {distributedLock.unlock();}
    }

九、锁的优化建议

  1. 尽量使用行级锁减少锁冲突,提高并发性能
  2. 合理设计索引确保锁能精确到所需的行,避免因无索引导致的表锁
  3. 控制事务大小缩短事务持有锁的时间
  4. 避免死锁
    • 以相同顺序访问表和行
    • 尽量使用较低的隔离级别
    • 设置合理的锁等待超时时间(innodb_lock_wait_timeout
  5. 使用 FOR UPDATE SKIP LOCKED在 MySQL 8.0 中,可以跳过被锁定的行,避免等待

九、总结

MySQL 提供了丰富的锁机制,从表级锁到行级锁,从共享锁到排他锁,每种锁都有其适用场景。理解并正确使用这些锁机制,是保证数据库高并发和数据一致性的关键。

在实际应用中,应根据业务场景选择合适的锁类型和隔离级别,同时通过合理的索引设计和事务管理来优化锁的使用,避免不必要的锁冲突和性能问题。特别是 InnoDB 存储引擎的行级锁机制,为高并发场景提供了强大的支持,是现代 MySQL 应用的首选。

http://www.dtcms.com/a/534540.html

相关文章:

  • 网站做中英版wordpress删除自豪的
  • 广告公司网站建设方案网站策划岗位要求
  • 武威市建设局网站 放管服做代金券的网站
  • 沈阳软件公司 网站制作wordpress xiu主题5.4
  • 百度推广怎么做的网站吗展示型网站有哪些功能
  • 水陆运输类网站如何建设信息门户网站建设
  • 合肥专业网站建设公司哪家好优化是什么意思?
  • 建立自己的网站平台须多少钱手机app开发制作公司
  • 石河子建设局网站做网站大概需要多少费用
  • 百度网站推广费用wordpress畅言评论使用教程
  • 鹤峰网站建设wordpress改logo不显示不出来
  • 网站开发属于什么会计科目国内做网站比较好的公司
  • 网站后台排版工具普通网站建设多少钱
  • 宁夏城乡建设厅网站电商网站建设基本流程图
  • 合肥企业建站系统模板页面设计需求
  • 网站设计中的技术分析建设像京东一样的网站
  • 阎良建设局 网站男女做暖网站
  • php网站开发经理招聘wordpress 菜单标题属性
  • 信用网站标准化建设二级注册建造师信息查询官网入口
  • 去国外做移动支付网站吗如何在百度上搜索到自己的网站
  • 网上做翻译兼职网站好数据导航 wordpress
  • 网站登记模板包头企业网站建设
  • 网站搭建服务器需要多少钱房地产网站推广
  • 永嘉网站优化企业邮箱来一个
  • 网站设计大概收费范围宜宾市规划建设局网站
  • 佛山专业的做网站的wordpress开发商城
  • 建单页网站网站正在建设中单页
  • 台州哪家做企业网站比较好2345网站登录
  • 橙色 网站六安政务中心网站
  • 做电子手抄报的网站建设一个网站平台