MySQL 事务是指一组数据库操作,在执行过程中要么全部成功,要么全部失败。事务可以保证数据库的原子性、一致性、隔离性和持久性(简称 ACID 特性),确保数据的正确性和一致性。

事务的四大特性(ACID)

  1. 原子性(Atomicity)

    • 事务中的所有操作要么全部成功,要么全部失败。即使系统发生崩溃,事务中的操作也不会部分提交。
    • 例如,银行转账操作,如果转账过程中涉及多个操作(如从账户A扣钱、往账户B存钱),要么两个操作都成功,要么两个操作都失败。
  2. 一致性(Consistency)

    • 事务执行前后,数据库都必须处于一致性状态。事务开始之前,数据库的状态是合法的,执行完事务后,数据库的状态也是合法的。
    • 例如,银行账户的余额在转账前后必须是合法的,不能出现负余额等不合理的状态。
  3. 隔离性(Isolation)

    • 每个事务的执行不受其他事务的干扰,即使是并发执行的事务,彼此之间也不会相互影响。
    • MySQL 提供了多种 隔离级别 来控制事务之间的相互影响,如 读未提交读已提交可重复读串行化
  4. 持久性(Durability)

    • 一旦事务提交,其对数据库的修改就是永久性的,即使系统崩溃,已提交的事务修改也会被持久保存。
    • 例如,银行转账成功后,即使系统宕机,账户余额的变动也不会丢失。

MySQL 事务的基本操作

  1. 开启事务(START TRANSACTION 或 BEGIN)

    • 开始一个新的事务。

      START TRANSACTION;
      -- 或者
      BEGIN;
  2. 提交事务(COMMIT)

    • 提交事务,将所有操作保存到数据库。

      COMMIT;
  3. 回滚事务(ROLLBACK)

    • 回滚事务,撤销自上次提交以来的所有操作。

      ROLLBACK;

MySQL 事务的隔离级别

MySQL 提供了四种 事务隔离级别,它们影响事务之间的可见性和干扰程度:

  1. READ UNCOMMITTED(读未提交)

    • 事务可以读取未提交事务的数据(脏读)。最低的隔离级别,可能导致数据不一致。
    • 优点:提高并发性。
    • 缺点:可能会发生脏读、不可重复读、幻读。
  2. READ COMMITTED(读已提交)

    • 事务只能读取已提交事务的数据,避免了脏读,但可能出现不可重复读的现象。
    • 优点:避免脏读,数据较一致。
    • 缺点:可能会出现不可重复读和幻读。
  3. REPEATABLE READ(可重复读)

    • 事务在执行期间,读取的数据会一直保持一致,避免了脏读和不可重复读。MySQL 默认的隔离级别。
    • 优点:避免了脏读和不可重复读。
    • 缺点:可能会发生幻读。
  4. SERIALIZABLE(串行化)

    • 最高的隔离级别,事务将会以串行方式执行。事务之间完全隔离,避免了所有的并发问题,但性能较差。
    • 优点:完全避免了脏读、不可重复读和幻读。
    • 缺点:性能差,事务执行的并发性降低。

MySQL 事务的锁机制

为了实现事务的隔离性,MySQL 使用了多种 锁机制,包括:

  1. 行锁(Row Lock)

    • 锁定某一行数据,其他事务不能修改该行,适用于 InnoDB 存储引擎。
  2. 表锁(Table Lock)

    • 锁定整张表,其他事务无法对表中的数据进行操作。表锁会影响其他操作的并发性,但加锁速度较快。
  3. 意向锁(Intention Lock)

    • 用于标识一个事务想要对某些行加锁,避免不同事务间发生冲突。
  4. 死锁(Deadlock)

    • 当两个事务互相等待对方持有的锁时,发生死锁,MySQL 会自动检测死锁并回滚其中一个事务。

事务的应用场景

  1. 银行转账

    • 转账操作需要保证从一个账户扣款、向另一个账户存款的操作要么全成功,要么全失败,避免数据不一致。
  2. 批量数据操作

    • 在处理多个插入、更新或删除操作时,使用事务可以确保这些操作要么全部成功,要么全部回滚。
  3. 订单支付系统

    • 订单创建、库存扣除、支付处理等操作需要在事务中执行,以保证订单状态的一致性。

总结

MySQL 事务是确保数据库操作原子性、一致性、隔离性和持久性(ACID)的一种机制。通过事务,可以确保一组操作要么全部成功,要么全部回滚,从而保证数据的完整性和一致性。在实际应用中,合理设置事务隔离级别和锁机制,可以优化数据库的性能和并发能力。


今夜有点儿凉
37 声望1 粉丝

今夜有点儿凉,乌云遮住了月亮。