Sql常见问题

SQL 锁机制概述

SQL 的锁机制用于保证多用户并发访问时的数据一致性和完整性。主要有两种锁:

共享锁(Shared Lock,读锁):允许多个事务同时读取同一数据,但不允许修改。

排他锁(Exclusive Lock,写锁):锁定的数据只能被持有锁的事务修改,其他事务无法读取或修改

锁的使用示例

✅ 读锁(共享锁)

情景:事务 A 读取数据 X,加读锁后,事务 B 也可以读取 X,但不能修改。

例子:如果事务 A 需要读取订单表中所有未处理的订单,它可以对这些行加读锁,让其他事务知道 A 正在查看这些数据,并且在 A 完成之前不会修改它们

❌ 写锁(排他锁) ✍️

情景:事务 A 对 X 加写锁后,事务 B 既不能读取也不能修改 X,直到事务 A 释放锁。

例子:如果事务 A 正在更新库存表,它会对需要更新的行加写锁,以确保更新过程中不会有其他事务干扰

⚖️ 共享锁 vs. 排他锁

共享锁(读锁)

排他锁(写锁) ✍️

并发性

允许多个事务同时读取

一个事务修改时,其他事务不能读或写

数据一致性

保证数据读取的一致性

保证数据更新的一致性和完整性

互斥性

读锁之间不互斥,多个事务可同时读取

写锁之间、读锁和写锁之间互斥

行锁 vs. 表锁

行锁(Row Lock)是数据库管理系统在行级别上的锁定策略,允许事务并发访问不同的行,提高性能 。

✅ 行锁优点:锁定特定行,而不是整个表,提高并发性!

❌ 表锁问题:当索引失效时,行锁可能退化为表锁,影响性能 ⚠️。

示例:

✅ 使用索引的 UPDATE 操作(行锁)

UPDATE orders SET order_status = 'processed' WHERE order_date = '2024-01-01';

MySQL 使用 order_date 索引,仅锁定满足条件的行。

❌ 未使用索引的 UPDATE 操作(可能退化为表锁)

UPDATE orders SET order_status = 'processed' WHERE order_status LIKE '%pending';

MySQL 无法使用索引,可能会锁定整个表,影响并发性能!


⛓️ 死锁(Deadlock) ⚠️

死锁是指两个事务相互等待对方释放锁,导致永久等待的情况。

⚠️ 死锁示例

1. 事务 A 锁定 账户 123,等待 账户 456 的锁释放。

2. 事务 B 锁定 账户 456,等待 账户 123 的锁释放。

3. 结果:两个事务互相等待,形成死锁!

解决方案:

合理设计事务执行顺序,避免交叉锁定不同资源。

设置超时时间 ⏳,让事务在等待超过一定时间后自动回滚。


间隙锁(Gap Lock)

间隙锁是 InnoDB 防止幻读(Phantom Read)的一种机制,它不锁定具体的行,而是锁定一个范围

例子:

1. 事务 A 执行查询

SELECT * FROM orders WHERE order_id BETWEEN 100 AND 200 FOR UPDATE;

2. 间隙锁生效,即使 ID=150 的订单不存在,事务 B 也无法插入 ID=150 的订单 !

⚠️ 副作用:可能会不必要地阻止其他事务插入数据,降低并发性!

✅ 解决方案:调整事务隔离级别(如从 可重复读 降级到 读已提交),减少间隙锁的使用。


主从复制(Master-Slave Replication)

主从复制用于在主服务器(Master)和从服务器(Slave)之间同步数据,通常用于读写分离高可用性

工作流程:

1. 主服务器 记录所有数据变更到二进制日志(Binary Log)

2. 从服务器 获取日志并应用变更,同步数据。

⚠️ 可能的问题:

数据延迟 ⏳:从服务器可能会比主服务器落后,影响一致性。

故障恢复复杂 ️:如果主服务器宕机,需要手动或自动切换到从服务器


总结:

合理使用锁机制,平衡数据一致性和性能。

优化索引,避免行锁退化为表锁,影响并发。

防范死锁,优化事务执行顺序,降低超时风险。

调整事务隔离级别,减少间隙锁的副作用。

主从复制有利于读写分离,但需注意复制延迟。

分库分表策略

15 | MySQL存储海量数据的最后一招:分库分表-后端存储实战课-极客时间

你可能感兴趣的:(数据库,java,大数据)