MySQL事务(一)

事务是什么

在MySQL中,事务是一组操作,这些操作要么全部执行成功,要么全部失败。事务的主要目的是保证数据的一致性和完整性。它确保当我们对数据库进行一系列操作时,要么所有操作都生效,要么如果其中任何一个操作失败,所有的操作都不会生效,就像从未执行过一样。

事务具有以下几个关键特性:

  1. 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败,没有中间状态。如果事务失败,所有的更改都会被撤销,回滚到事务开始之前的状态。

  2. 一致性(Consistency):事务执行前后,数据库都必须处于一致的状态。事务保证从一个一致状态转换到另一个一致状态。

  3. 隔离性(Isolation):并发执行的事务之间互不干扰。一个事务的中间状态对其他事务是不可见的,不同的事务彼此隔离。

  4. 持久性(Durability):一旦事务提交,所做的更改就会永久保存,即使系统发生故障也不会丢失。

举个例子,当你在网上购物时,涉及到多个步骤,如扣款、更新库存、生成订单等,这些步骤需要作为一个整体来执行。如果其中任何一个步骤失败,整个购物操作都应该失败,这样可以避免出现扣款成功但订单生成失败的情况。

事务通常用于处理复杂的、涉及多个步骤的操作,确保在处理过程中即使出现错误,数据也不会处于不一致的状态。通过使用事务,数据库系统可以保证数据的可靠性和一致性,特别是在高并发的环境中。

为什么需要事务

事务的出现是为了确保在对数据库进行操作时,能够保持数据的一致性、完整性和可靠性。以下是事务出现的主要原因:

  1. 数据一致性和完整性

    在处理多个相关联的数据库操作时,事务确保这些操作要么全部成功,要么全部失败。例如,在银行转账中,从一个账户扣款并向另一个账户存款,这两个操作必须作为一个整体来执行。如果只完成了扣款而未能完成存款,数据库就会出现不一致的状态。
  2. 处理复杂操作

    一些操作涉及多个步骤,如果每一步都独立执行,出现问题时很难保证数据的一致性。事务可以将这些步骤组合成一个原子操作,确保所有步骤要么全部完成,要么全部撤销。
  3. 并发控制

    在多用户并发访问数据库的环境中,事务可以确保不同用户的操作互不干扰。例如,两个用户同时修改同一条记录时,事务可以确保一个用户的修改不会被另一个用户的修改所覆盖,从而避免数据冲突和不一致。
  4. 错误恢复

    事务提供了回滚机制,允许在操作失败时撤销已经完成的部分操作,恢复到初始状态。这对系统在遇到错误或异常情况时的恢复非常重要,确保数据的安全和可靠。
  5. 业务逻辑的保证

    许多应用程序需要确保特定的业务逻辑得到满足。例如,在电商系统中,订单的创建和库存的更新需要在同一个事务中完成,以确保库存数量的准确性和订单信息的一致性。

储存引擎是否支持事务

在MySQL中,并不是所有的存储引擎都支持事务。

  1. InnoDB

    • InnoDB 是 MySQL 默认的存储引擎,也是最常用的事务型存储引擎。它支持所有的 ACID 特性,包括原子性、一致性、隔离性和持久性。InnoDB 提供了行级锁定、外键支持以及崩溃恢复能力,使其非常适合处理需要高并发和高可靠性的应用。
  2. NDB Cluster

    • NDB Cluster 是 MySQL Cluster 的存储引擎,设计用于分布式数据库系统。它支持事务和高可用性,能够在多个节点之间分布数据并进行故障恢复。
  3. TokuDB

    • TokuDB 是一个专注于高写入性能和高压缩率的存储引擎。它支持事务和 MVCC(多版本并发控制),适用于需要处理大量数据的应用。
  4. MyRocks

    • MyRocks 是基于 RocksDB 的存储引擎,优化了写入性能和存储效率。它支持事务和 MVCC,适用于需要高效写入和空间优化的应用场景。
  5. Spider

    • Spider 存储引擎是一个支持分布式的存储引擎,允许将数据分布在多个 MySQL 实例上。它支持分布式事务,可以实现跨多个物理节点的事务处理。

需要注意的是,MySQL 中一些常用的存储引擎,如 MyISAM,不支持事务。这意味着使用这些引擎的表不能享受事务带来的数据一致性和可靠性保障。

事务的隔离性

隔离性是事务管理中的一个关键属性,它确保同时并发执行的事务互不干扰,每个事务的中间状态对其他事务是不可见的。隔离性通过控制事务之间的相互访问,避免了数据不一致和竞争条件的问题。

在数据库中,并发执行的事务可能会导致以下问题:

  1. 脏读(Dirty Read)

    • 一个事务读取了另一个未提交事务修改的数据。如果这个修改被回滚,读取到的数据就是无效的。
  2. 不可重复读(Non-repeatable Read)

    • 在一个事务中,多次读取同一数据行,每次读取的数据可能不同,因为其他事务可能在这期间修改了该数据。
  3. 幻读(Phantom Read)

    • 一个事务在两次查询期间,其他事务插入或删除了数据,导致两次查询结果集不同。

为了控制这些问题,SQL标准定义了四种事务隔离级别,每种隔离级别对上述问题的控制力度不同。

隔离级别(Isolation Levels)

  1. 未提交读(Read Uncommitted)

    • 描述:事务可以读取其他未提交事务的数据。
    • 优点:最低的隔离级别,允许最高的并发性。
    • 缺点:可能导致脏读。
    • 避免问题:不避免脏读、不可重复读和幻读。
  2. 提交读(Read Committed)

    • 描述:事务只能读取其他已提交事务的数据。
    • 优点:避免了脏读。
    • 缺点:可能导致不可重复读。
    • 避免问题:避免脏读,但不避免不可重复读和幻读。
  3. 可重复读(Repeatable Read)

    • 描述:事务在开始时读取的数据,在事务期间保持一致。事务中的所有读操作都只能看到事务开始时的状态,其他事务的更新在本事务中不可见。
    • 优点:避免了脏读和不可重复读。
    • 缺点:可能导致幻读。
    • 避免问题:避免脏读和不可重复读,但不完全避免幻读。
  4. 串行化(Serializable)

    • 描述:最高的隔离级别,通过强制事务串行执行来避免所有并发问题。每个事务按照顺序逐个执行,避免了所有的并发读写冲突。
    • 优点:完全避免脏读、不可重复读和幻读。
    • 缺点:并发性最低,可能导致性能问题。
    • 避免问题:完全避免脏读、不可重复读和幻读。

隔离级别比较

隔离级别脏读不可重复读幻读
未提交读可能可能可能
提交读避免可能可能
可重复读避免避免可能
串行化避免避免避免

选择隔离级别

选择哪种隔离级别取决于应用的需求和性能要求。一般来说:

  • 对于需要最高并发性能但对数据一致性要求不高的应用,可以选择较低的隔离级别(如未提交读或提交读)。
  • 对于数据一致性要求高的应用(如金融系统),则应选择较高的隔离级别(如可重复读或串行化)。

大多数数据库管理系统(如MySQL的InnoDB存储引擎)默认使用可重复读隔离级别,因为它提供了较好的性能与数据一致性之间的平衡。

查看和设置隔离级别

在MySQL中,可以通过SQL语句查看和设置事务的隔离级别。以下是如何查看和设置隔离级别的详细步骤:

查看当前隔离级别

要查看当前的事务隔离级别,可以使用以下命令:

SELECT @@transaction_isolation;

这个命令会返回当前的事务隔离级别,例如 "READ-COMMITTED", "REPEATABLE-READ", "READ-UNCOMMITTED", 或 "SERIALIZABLE"。

设置隔离级别

可以在全局级别或会话级别设置事务隔离级别。全局级别设置会影响所有新的会话,而会话级别设置只影响当前会话。

设置全局隔离级别

设置全局隔离级别使用 SET GLOBAL 语句:

SET GLOBAL transaction_isolation = 'REPEATABLE-READ';

注意:设置全局隔离级别需要具有 SUPER 权限。此外,已经打开的会话不会受到此更改的影响,只有新的会话会使用新的隔离级别。

设置会话隔离级别

设置当前会话的隔离级别使用 SET SESSION 语句:

SET SESSION transaction_isolation = 'READ-COMMITTED';

这个设置只影响当前的数据库连接会话。

示例操作

  1. 查看当前隔离级别
    SELECT @@transaction_isolation;
    

    输出示例:

    +------------------------+
    | @@transaction_isolation|
    +------------------------+
    | REPEATABLE-READ        |
    +------------------------+
    
  2. 设置全局隔离级别为 "SERIALIZABLE"
    SET GLOBAL transaction_isolation = 'SERIALIZABLE';
    
  3. 设置会话隔离级别为 "READ-COMMITTED"
    SET GLOBAL transaction_isolation = 'SERIALIZABLE';
    

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值