Skip to content

Latest commit

 

History

History
120 lines (75 loc) · 4.26 KB

File metadata and controls

120 lines (75 loc) · 4.26 KB

事务与锁基础

事务和锁是 MySQL 中保证数据正确性与并发安全的核心机制。查询数据更多关注“如何把数据取出来”,而事务与锁关注的是“多个人同时操作数据时,如何保证结果仍然正确”。

什么是事务

事务(Transaction)是一组不可再分的 SQL 操作,这组操作要么全部执行成功,要么全部执行失败,不会只完成一部分。

典型场景是转账:

  1. A 账户扣款
  2. B 账户加款

这两个步骤必须作为一个整体执行。如果只扣款成功、加款失败,数据就会出现错误,因此需要事务保证一致性。

事务的四个特性

事务通常用 ACID 来描述:

  • 原子性(Atomicity):事务中的操作要么全部成功,要么全部失败。
  • 一致性(Consistency):事务执行前后,数据都必须处于合法状态。
  • 隔离性(Isolation):多个事务并发执行时,彼此之间尽量不互相干扰。
  • 持久性(Durability):事务一旦提交,结果就会被持久保存。

事务的基本操作

MySQL 中常见的事务控制语句如下:

START TRANSACTION;

UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;

COMMIT;

如果执行过程中发现异常,可以回滚:

START TRANSACTION;

UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;

ROLLBACK;

其中:

  • START TRANSACTION 表示开启事务
  • COMMIT 表示提交事务
  • ROLLBACK 表示回滚事务

什么是锁

锁(Lock)是数据库在并发场景下保护数据的一种机制。当多个会话同时读写同一批数据时,MySQL 通过加锁来避免脏数据、覆盖更新和不一致问题。

可以把锁理解为“先占用资源,再进行操作”的规则。谁先拿到锁,谁就先操作;其他事务需要等待或按隔离规则读取。

常见锁类型

共享锁和排他锁

  • 共享锁(Shared Lock,S 锁):允许多个事务同时读取同一条数据,但不允许修改。
  • 排他锁(Exclusive Lock,X 锁):拿到锁的事务可以读写该数据,其他事务通常不能再加共享锁或排他锁。

行锁和表锁

  • 行锁:只锁定某几行记录,并发能力更强,影响范围更小。
  • 表锁:锁定整张表,实现简单,但并发性能较低。

InnoDB 一般以行锁为主,因此更适合高并发业务场景。

为什么需要锁

如果没有锁,在并发环境下容易出现以下问题:

  • 脏读:读取到另一个事务尚未提交的数据。
  • 不可重复读:同一个事务中两次读取同一条记录,结果不同。
  • 幻读:同一个事务中两次按条件查询,第二次多出或少了记录。
  • 丢失更新:多个事务同时修改同一条记录,后一次覆盖前一次结果。

事务隔离级别

MySQL 常见事务隔离级别包括:

  • READ UNCOMMITTED:隔离级别最低,可能出现脏读。
  • READ COMMITTED:只能读到已提交数据,能避免脏读。
  • REPEATABLE READ:同一事务中多次读取结果保持一致,是 InnoDB 默认级别。
  • SERIALIZABLE:隔离级别最高,并发能力最低,安全性最强。

隔离级别越高,数据越安全,但并发性能通常越低,因此实际使用时要在一致性与性能之间平衡。

查看和设置事务隔离级别

可以用下面的语句查看当前会话的隔离级别:

SELECT @@transaction_isolation;

也可以设置当前会话的隔离级别:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

使用事务与锁时的建议

  1. 事务尽量短小,避免长事务占用锁太久。
  2. 尽量通过索引命中目标行,减少锁范围。
  3. 先查询再更新的业务,要注意并发竞争问题。
  4. 批量更新和大事务要谨慎,避免阻塞其他会话。
  5. 在高并发系统中,要结合事务隔离级别一起分析锁问题。

小结

事务解决的是“操作要不要作为一个整体成功”的问题,锁解决的是“并发操作时谁可以先访问数据”的问题。掌握这两个基础概念后,再学习 MySQL 的更新、删除、索引优化和性能调优会更容易建立完整认识。