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

网站建设销售客户开发江宁做网站价格

网站建设销售客户开发,江宁做网站价格,网上做论文的网站有哪些,如何开发软件appMySQL 锁机制是保证数据一致性和并发控制的核心组件,主要分为乐观锁和悲观锁两大类。以下从实现原理到实战应用进行全面解析。 一、悲观锁(Pessimistic Locking) 1. 基本概念 核心思想:假定并发冲突经常发生,访问数据…

MySQL 锁机制是保证数据一致性和并发控制的核心组件,主要分为乐观锁和悲观锁两大类。以下从实现原理到实战应用进行全面解析。

一、悲观锁(Pessimistic Locking)

1. 基本概念

核心思想:假定并发冲突经常发生,访问数据前先加锁

特点:

由数据库原生支持

适合写多读少场景

保证强一致性

可能引发死锁

2. InnoDB 悲观锁实现方式

(1) 共享锁(S锁)

SELECT * FROM products WHERE id = 1 LOCK IN SHARE MODE;

-- 或

SELECT * FROM products WHERE id = 1 FOR SHARE; -- MySQL 8.0+

允许多事务并发读取

阻塞其他事务获取排他锁

事务提交/回滚后释放

(2) 排他锁(X锁)

SELECT * FROM products WHERE id = 1 FOR UPDATE;

独占锁,阻塞其他所有锁请求

自动应用于 UPDATE/DELETE 语句

(3) 意向锁(Intention Locks)

意向共享锁(IS):事务准备加共享锁前先获取

意向排他锁(IX):事务准备加排他锁前先获取

表级锁,用于快速判断表中是否有行锁

3. 行锁算法

锁类型 描述 SQL示例

记录锁(Record Lock) 锁定索引记录 WHERE id = 1 FOR UPDATE

间隙锁(Gap Lock) 锁定索引记录间隙 WHERE id BETWEEN 10 AND 20 FOR UPDATE

临键锁(Next-Key Lock) 记录锁+间隙锁组合 InnoDB 默认行锁算法

插入意向锁(Insert Intention Lock) INSERT操作设置的间隙锁 并发插入优化

4. 悲观锁实战案例

库存扣减场景:

START TRANSACTION;

-- 1. 查询并锁定商品

SELECT stock FROM products WHERE id = 1001 FOR UPDATE;

-- 2. 检查库存

-- 3. 更新库存

UPDATE products SET stock = stock - 1 WHERE id = 1001;

COMMIT;

二、乐观锁(Optimistic Locking)

1. 基本概念

核心思想:假定并发冲突很少发生,提交时检测冲突

特点:

应用层实现

适合读多写少场景

高并发性能好

需处理冲突重试

2. 实现方式

(1) 版本号机制

-- 表设计

ALTER TABLE products ADD COLUMN version INT DEFAULT 0;

-- 更新逻辑

UPDATE products

SET stock = stock - 1, version = version + 1

WHERE id = 1001 AND version = 当前版本;

-- 检查影响行数,0表示冲突

(2) 时间戳机制

ALTER TABLE products ADD COLUMN update_time TIMESTAMP;

UPDATE products

SET stock = stock - 1, update_time = CURRENT_TIMESTAMP

WHERE id = 1001 AND update_time = 上次查询时间;

(3) 条件判断(业务字段)

UPDATE accounts

SET balance = balance - 100

WHERE id = 1 AND balance >= 100;

-- 余额不足时自动失败

3. 乐观锁实战案例

Java 实现示例:

public boolean deductStock(Long productId, int quantity) {int retry = 3;while (retry-- > 0) {Product product = productDao.selectById(productId);int updated = productDao.updateStock(productId, quantity, product.getVersion());if (updated > 0) {return true;}// 短暂等待后重试Thread.sleep(50);}return false;
}

三、锁机制对比

维度

悲观锁

乐观锁

并发性能

差(锁竞争)

好(无阻塞)

冲突处理

预防冲突

检测冲突

实现层面

数据库层面

应用层面

适用场景

写多读少、强一致

读多写少、高并发

典型应用

银行转账

商品秒杀

四、InnoDB 锁的详细分类

1. 按锁粒度分类

锁类型

描述

开销

表级锁

锁定整张表

行级锁

锁定索引记录

页级锁

锁定数据页(InnoDB不支持)

2. InnoDB 特殊锁

锁类型

描述

作用

AUTO-INC锁

自增列插入时的表锁

保证自增顺序

谓词锁

空间索引使用的锁

GIS 操作

外键约束锁

外键检查时的锁

保证参照完整性

五、死锁处理与优化

1. 死锁产生条件

互斥条件

请求与保持条件

不剥夺条件

环路等待条件

2. 死锁检测

-- 查看最近死锁信息

SHOW ENGINE INNODB STATUS\G

-- 重点关注 LATEST DETECTED DEADLOCK 部分

3. 避免死锁策略

统一访问顺序:所有事务按相同顺序访问资源

减小事务粒度:缩短事务执行时间

设置超时:innodb_lock_wait_timeout = 50(默认50秒)

使用乐观锁:避免长时间持有锁

六、锁监控与性能优化

1. 锁等待监控

-- 查看当前锁等待

SELECT * FROM performance_schema.events_waits_current

WHERE EVENT_NAME LIKE '%lock%';

-- 查看被阻塞的事务

SELECT * FROM sys.innodb_lock_waits;

2. 锁相关参数优化

# 死锁检测开关(高并发时可临时关闭)

innodb_deadlock_detect = ON

# 锁等待超时(秒)

innodb_lock_wait_timeout = 30

# 行锁升级阈值(避免行锁过多升级为表锁)

innodb_row_lock_upgrade_threshold = 1000

七、实战场景锁选择指南

一、电商库存管理场景

案例1.1:秒杀系统实现(乐观锁方案)

业务需求

  • 1000件特价商品限时秒杀
  • 预计10万用户同时抢购
  • 必须防止超卖

数据库设计

CREATE TABLE `seckill_products` (`id` BIGINT NOT NULL,`name` VARCHAR(100),`stock` INT NOT NULL COMMENT '库存',`version` INT DEFAULT 0 COMMENT '乐观锁版本号',PRIMARY KEY (`id`)
) ENGINE=InnoDB;INSERT INTO `seckill_products` VALUES (1001, 'iPhone 14', 1000, 0);

Java 实现代码

public boolean seckill(Long productId, Integer userId) {int retryTimes = 3;while (retryTimes-- > 0) {SeckillProduct product = productDao.getById(productId);if (product.getStock() <= 0) {return false;}int affectedRows = productDao.reduceStockWithVersion(productId, product.getVersion());if (affectedRows > 0) {orderDao.createOrder(productId, userId);return true;}// 短暂等待后重试try { Thread.sleep(100); } catch (InterruptedException e) { break; }}return false;
}

SQL 实现

<!-- MyBatis 映射 -->
<update id="reduceStockWithVersion">UPDATE seckill_productsSET stock = stock - 1,version = version + 1WHERE id = #{id}AND stock > 0AND version = #{version}
</update>

压测结果

并发用户数

悲观锁方案TPS

乐观锁方案TPS

超卖情况

1,000

120

850

5,000

35

620

10,000

8

430

优化点

  1. 结合Redis预减库存,减轻数据库压力
  2. 异步记录订单,提高响应速度
  3. 设置分段锁(如将商品分成10个库存段)

二、银行转账场景(悲观锁方案)

案例2.1:跨账户资金转账

业务需求

  • 转账操作必须保证原子性
  • 高金额交易需要严格一致性
  • 防止并发操作导致余额错误

数据库表结构

CREATE TABLE `accounts` (`id` BIGINT PRIMARY KEY,`account_no` VARCHAR(20) UNIQUE,`balance` DECIMAL(15,2) NOT NULL,`frozen_amount` DECIMAL(15,2) DEFAULT 0
) ENGINE=InnoDB;INSERT INTO `accounts` VALUES 
(1, '6225880111111111', 10000.00, 0),
(2, '6225880222222222', 5000.00, 0);

事务实现代码

@Transactional(rollbackFor = Exception.class)
public void transfer(String fromAccount, String toAccount, BigDecimal amount) {// 1. 锁定转出账户(避免死锁,按账号排序锁定)Account from = accountDao.lockByAccountNo(fromAccount);if (from.getBalance().compareTo(amount) < 0) {throw new BusinessException("余额不足");}// 2. 锁定转入账户Account to = accountDao.lockByAccountNo(toAccount);// 3. 执行转账accountDao.reduceBalance(fromAccount, amount);accountDao.addBalance(toAccount, amount);// 4. 记录交易流水transactionDao.record(from.getId(), to.getId(), amount);
}

SQL 锁定实现

<!-- 锁定账户 -->
<select id="lockByAccountNo" resultType="Account">SELECT * FROM accounts WHERE account_no = #{accountNo}FOR UPDATE  -- 排他锁
</select>

死锁预防方案

  1. 统一获取锁的顺序(按账号排序)
List<String> accounts = Arrays.asList(fromAccount, toAccount);
accounts.sort(String::compareTo);
  1. 设置锁等待超时

SET innodb_lock_wait_timeout = 5; -- 5秒超时

  1. 添加重试机制
@Retryable(value = {DeadlockLoserDataAccessException.class}, maxAttempts = 3, backoff = @Backoff(delay = 100))
public void transferWithRetry(...) {// 转账逻辑
}

三、机票订票系统(混合锁方案)

案例3.1:高并发座位选择

业务特点

  • 读多写少(大量查询余票,少量下单)
  • 选座时需要临时锁定座位
  • 最终支付完成才真正扣减

数据库设计

CREATE TABLE `flights` (`id` BIGINT PRIMARY KEY,`flight_no` VARCHAR(20),`total_seats` INT,`available_seats` INT,`version` INT DEFAULT 0
);CREATE TABLE `seat_locks` (`id` BIGINT PRIMARY KEY,`flight_id` BIGINT,`seat_no` VARCHAR(10),`user_id` BIGINT,`lock_time` DATETIME,`expire_time` DATETIME,INDEX `idx_flight_seat` (`flight_id`, `seat_no`)
);

分阶段锁策略

  1. 查询阶段(无锁)

SELECT available_seats FROM flights WHERE id = 1001;

  1. 选座阶段(乐观锁+记录锁)
// 1. 检查座位是否可用(无锁快照读)
SeatLock existLock = seatLockDao.findByFlightAndSeat(flightId, seatNo);
if (existLock != null && existLock.getExpireTime().after(now())) {throw new BusinessException("座位已被锁定");
}// 2. 尝试锁定座位(乐观锁)
boolean locked = seatLockDao.tryLock(flightId, seatNo, userId, 10min);
if (!locked) {throw new BusinessException("锁定座位失败");
}
  1. 支付阶段(悲观锁)
@Transactional
public void confirmPayment(Long orderId) {// 1. 锁定订单和航班Order order = orderDao.lockById(orderId);Flight flight = flightDao.lockById(order.getFlightId());// 2. 验证座位锁定状态SeatLock lock = seatLockDao.findLock(order.getFlightId(), order.getSeatNo());if (lock == null || !lock.getUserId().equals(order.getUserId())) {throw new BusinessException("座位锁定已失效");}// 3. 扣减余票(悲观锁保证原子性)flightDao.reduceSeats(order.getFlightId(), 1);// 4. 删除临时锁定seatLockDao.unlock(lock.getId());
}

性能对比

方案

100并发查询

100并发下单

数据一致性

纯悲观锁

120 QPS

15 TPS

强一致

混合锁方案

850 QPS

80 TPS

最终一致

其他一些场景:

场景1:秒杀系统

推荐方案:乐观锁 + 缓存

UPDATE seckill_products

SET stock = stock - 1

WHERE id = 1001 AND stock > 0;

场景2:财务系统

推荐方案:悲观锁(SELECT FOR UPDATE)

原因:需要强一致性保证

场景3:报表生成

推荐方案:共享锁(LOCK IN SHARE MODE)

优势:允许多个查询并发读取

下面通过多个详细的业务场景案例,深入分析乐观锁和悲观锁的具体应用,以及在不同并发条件下的表现和优化方案。

四、分布式锁场景(跨服务锁定)

案例4.1:跨系统订单处理

业务需求

  • 订单服务与库存服务独立部署
  • 创建订单时需要锁定多个服务的资源
  • 必须避免不同服务间数据不一致

实现方案

  1. Redis分布式锁(初步锁定)
public boolean createOrder(OrderDTO order) {// 1. 获取分布式锁String lockKey = "lock:product:" + order.getProductId();boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, order.getUserId(), 10, TimeUnit.SECONDS);if (!locked) {throw new BusinessException("系统繁忙,请重试");}try {// 2. 调用库存服务(HTTP)inventoryService.reduceStock(order.getProductId(), order.getQuantity());// 3. 创建订单(本地事务)orderService.createLocalOrder(order);} finally {// 4. 释放锁redisTemplate.delete(lockKey);}
}
  1. 最终一致性方案(Saga模式)
// Saga执行器
@Saga
public void createOrderSaga(OrderDTO order) {// 步骤1:预留库存saga.addStep(() -> inventoryService.blockStock(order),() -> inventoryService.unblockStock(order));// 步骤2:创建订单saga.addStep(() -> orderService.createPendingOrder(order),() -> orderService.cancelPendingOrder(order));// 步骤3:确认操作saga.addStep(() -> {inventoryService.confirmBlock(order);orderService.confirmOrder(order);});
}

异常处理对比

方案

网络分区处理

服务宕机恢复

实现复杂度

分布式锁

依赖超时

可能死锁

中等

Saga模式

自动补偿

状态可恢复

五、监控与排查工具

5.1 锁等待分析

sql

复制

-- 查看当前锁等待
SELECT r.trx_id waiting_trx_id,r.trx_mysql_thread_id waiting_thread,b.trx_id blocking_trx_id,b.trx_mysql_thread_id blocking_thread
FROM performance_schema.events_waits_current w
JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_instance
JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_instance;

5.2 锁争用热点分析

sql

复制

-- 找出等待时间最长的锁
SELECT object_schema,object_name,index_name,lock_type,lock_mode,COUNT(*) as conflict_count,AVG(TIMESTAMPDIFF(SECOND, wait_started, now())) as avg_wait_seconds
FROM sys.innodb_lock_waits
GROUP BY object_schema, object_name, index_name
ORDER BY avg_wait_seconds DESC;

六、最佳实践总结

  1. 锁选择原则
    • 读多写少 → 乐观锁
    • 写多读少 → 悲观锁
    • 跨服务操作 → 分布式锁+Saga
  1. 性能优化技巧
    • 减小锁粒度(行锁而非表锁)
    • 缩短锁持有时间(避免事务中包含RPC调用)
    • 添加合理的重试机制
  1. 避免常见陷阱
    • 乐观锁的重试次数不宜过多(通常3次)
    • 悲观锁必须按固定顺序获取
    • 分布式锁必须设置超时时间

通过以上实际场景的深度分析,可以看出没有放之四海而皆准的锁方案,必须根据具体业务特点、并发规模和数据一致性要求来选择最合适的并发控制策略。


 

八、最佳实践建议

索引设计:

确保锁定的行有索引,否则会锁表

事务设计:

尽量短小

避免用户交互

合理设置隔离级别

监控:

定期检查 information_schema.INNODB_LOCKS

混合使用:

关键业务可结合悲观锁+乐观锁

通过深入理解 MySQL 锁机制,可以针对不同业务场景选择最合适的并发控制策略,在保证数据一致性的同时获得最佳性能。

http://www.dtcms.com/wzjs/595379.html

相关文章:

  • 做一个美食网站怎么做江苏招标网中标公告
  • 站长查询站长工具网站在政务新媒体建设方案
  • 南京做网站需要多少钱wordpress字体在哪
  • 南宫建设局网站首页asp网站显示建设中
  • 中国新农村建设网站投稿做网站用vue还是用jquery
  • 昆明网站制作服务商价格优化网站建设
  • 做网站横幅的软件WordPress二维码动态图片
  • 台州手机网站制作施工企业环境管理体系文件
  • 网站建设中网站需求分析的理解白云网站建设哪家好
  • 湘西北京网站建设2016年建设网站赚钱吗
  • 网站服务器主机配置wordpress mip
  • 来年做啥网站能致富龙元建设网站
  • 建设教育工程网站公司简介概况怎么写
  • 可信网站认证哪里有wordpress翻页代码
  • 洛江区建设局网站大一html网页制作
  • 中国建设银网站wordpress 微博 插件
  • 做海淘的网站做海淘的网站开发免费app
  • 快云服务器怎么做网站保健食品东莞网站建设
  • 北京网站推广排名外包做网站预算表
  • 北京高端网站制作北京注册公司要求
  • 网站开发没有完成 需要赔偿吗商标图案大全大图 logo
  • 网站开发和网页开发有什么区别python基础教程百度云
  • 武山建设局网站近期国外重大新闻事件
  • 湖南省郴州市湘南学院电商网站建设优化
  • 做哪类英文网站赚钱阿里云有主体新增网站
  • 51网站空间相册参考消息电子版报纸
  • 自己制作一个网站怎么制作深圳快速网站制作哪家快
  • 长沙网站建设软件wordpress商品分类
  • 如何写一份食品的网站建设规划交互设计考研院校
  • 上海信息公司做网站网络销售这个工作到底怎么样