跳到主要内容

MySQL 事务与锁机制

事务概述

我在实际开发中会使用事务确保数据的一致性和完整性。事务是数据库中的逻辑单元,其中的多条 SQL 语句要么全部成功要么全部失败,我通过事务能有效避免数据不一致问题。

事务的 ACID 特性

原子性
事务中的所有操作要么全部完成要么全部不做

一致性
事务执行前后数据库都保持一致状态

隔离性
多个事务同时执行时相互独立互不干扰

持久性
事务提交后的结果是永久性的系统故障也不影响已提交数据

事务的使用

在 MySQL 中使用事务时我一般通过以下方式

START TRANSACTION;
-- 执行SQL操作
COMMIT;

如果事务过程中发生错误我会通过以下操作回滚

START TRANSACTION;
-- 执行SQL操作
ROLLBACK;

事务的隔离级别

我在实际中会根据业务需求选择合适的事务隔离级别,这些级别决定事务间相互影响的程度。MySQL 支持以下四种隔离级别

读未提交
事务可读取未提交数据可能会发生脏读

读已提交
只能读取已提交数据避免脏读但仍有不可重复读和幻读问题。Oracle 数据库默认使用此级别。

可重复读
在同一事务中多次读取同一行数据结果一致可避免脏读和不可重复读。MySQL InnoDB 默认使用此级别,并通过 MVCC 和间隙锁解决了大部分幻读问题。

串行化
强制事务串行执行避免所有读写异常但并发性能较低

我在需要修改隔离级别时会使用以下操作语句

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

锁机制概述

我在使用事务时经常需要考虑锁机制以保证数据一致性和并发性能。MySQL 中常用行级锁和表级锁

行级锁
只锁定被选中的行并发性能较高 InnoDB 存储引擎支持行级锁

表级锁
锁定整个表适用于读多写少的场景 MyISAM 存储引擎多用表级锁

意向锁
这是一种表级锁用于标记事务打算对表中部分行加锁从而在加锁前避免冲突

死锁处理

在高并发下可能出现死锁即多个事务互相等待对方释放资源而无法继续执行。InnoDB 能自动检测死锁并回滚其中一个事务打破僵局同时记录死锁信息以便我后续排查问题

代码示例

在实际场景中我为避免并发修改同一行数据导致不一致通常会先加锁再更新

START TRANSACTION;

-- 对特定用户行加锁防止其他事务修改
SELECT * FROM accounts WHERE user_id = 1 FOR UPDATE;

-- 更新账户余额
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;

COMMIT;

最佳实践

合理选择隔离级别平衡数据一致性与性能
使用行级锁以提升并发性能
避免长时间持有锁减少死锁风险
定期监控和分析锁等待优化数据库设计
确保事务尽量简短减少资源占用