InnoDB存储引擎对 select 语句的加锁

对 select 语句支持两种一致性的锁定读操作:

  1. select … for update : 对读取的行记录加排他锁(X)。
  2. select … lock in share mode : 对读取的行记录加共享锁(S)。
### SQL中的加锁机制 在SQL中,加锁是一种用于控制并发访问的技术,能够防止多个事务同时修改相同的数据而导致数据不一致。常见的加锁方式分为共享锁(Share Locks)和排他锁(Exclusive Locks),分别对应读操作和写操作。 #### 1. Oracle 中的加锁语法 在Oracle数据库中,可以通过 `LOCK TABLE` 命令显式地对表施加锁定。以下是具体的语法: ```sql LOCK TABLE table_name IN lock_mode MODE; ``` 其中,`lock_mode` 可以取以下几种模式之一: - **ROW SHARE**: 允许多个事务同时持有 ROW SHARE 锁。 - **ROW EXCLUSIVE**: 排除其他事务获取更高级别的锁,但仍允许查询。 - **SHARE UPDATE**: 类似于 ROW EXCLUSIVE,但在某些版本中可能有不同行为。 - **SHARE**: 阻止其他事务对该表进行更新或删除操作。 - **SHARE ROW EXCLUSIVE**: 更严格的锁级别,阻止其他事务获得 SHARE 或更高级别的锁。 - **EXCLUSIVE**: 完全独占该表,不允许任何其他事务对其进行更改或查询。 示例代码如下: ```sql -- 对 employees 表加排他锁 LOCK TABLE employees IN EXCLUSIVE MODE; ``` 此命令会阻塞其他事务对该表的操作直到当前事务提交或回滚[^3]。 --- #### 2. MySQL 中的加锁语法 MySQL 支持两种主要类型的锁:表级锁和行级锁。对于 InnoDB 存储引擎,默认情况下使用的是行级锁,而 MyISAM 使用表级锁。 ##### (1)表级锁 通过 `LOCK TABLES` 和 `UNLOCK TABLES` 实现表级锁。例如: ```sql LOCK TABLES employees WRITE; -- 获取写锁 LOCK TABLES employees READ; -- 获取读锁 ``` 需要注意的是,在释放锁之前无法执行涉及未锁定表的查询或其他 DML 操作。解锁可通过以下语句完成: ```sql UNLOCK TABLES; ``` ##### (2)行级锁 InnoDB 自动管理行级锁,无需手动干预。然而,也可以通过特定关键字来增强控制能力。例如: - **SELECT ... FOR UPDATE**: 将选中的行加上排他锁,适用于即将被修改的记录。 - **SELECT ... LOCK IN SHARE MODE**: 添加共享锁,允许多个事务并行读取同一组数据。 下面是一个典型的例子: ```sql START TRANSACTION; -- 查询部门 ID 为 1 的员工,并对其加排他锁 SELECT * FROM employees WHERE department_id = 1 FOR UPDATE; UPDATE employees SET salary = salary * 1.1 WHERE department_id = 1; COMMIT; ``` 在此过程中,只有当事务结束时才会释放所持有的锁[^4]。 --- #### 3. PostgreSQL 中的加锁语法 PostgreSQL 提供了多种锁类型,支持从低粒度到高粒度的不同需求。常用的加锁方法包括隐式锁和显式锁。 ##### (1)隐式锁 PostgreSQL 默认会在适当的时候自动应用必要的锁。比如,INSERT、UPDATE 和 DELETE 操作都会触发行级锁;而 SELECT 不会主动请求锁除非指定了特殊选项。 ##### (2)显式锁 可以利用 `SELECT ... FOR UPDATE` 或者直接调用 `pg_advisory_lock()` 函数实现自定义逻辑下的锁定功能。例如: ```sql BEGIN; -- 显式锁定某一行 SELECT id, name FROM products WHERE id = 10 FOR UPDATE; -- 更新产品价格 UPDATE products SET price = price * 1.1 WHERE id = 10; END; ``` 另外还可以借助存储过程或者扩展模块进一步封装复杂的业务场景处理流程[^2]。 --- ### 性能优化注意事项 尽管加锁有助于保障数据一致性,但如果滥用则可能导致死锁现象发生从而降低整体效率。因此应当遵循以下几个原则合理设计程序结构: - 尽量缩短持有锁的时间长度; - 确保按照固定的顺序访问资源对象; - 考虑采用乐观锁代替悲观锁策略减少冲突概率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值