MySQL的数据库事务、ACID特性以及实战案例

2025-12-04 0 820

什么是数据库事务,为什么它如此重要?

数据库事务是数据库中一个操作单元,包含一组被整体执行和写入的多个数据操作。这些操作可以包括创建(Create)读取(Read)更新(Update)删除(Delete) 操作。

事务过程中的数据处于不一致的状态,因为事务正在对数据库进行修改。一旦事务中的所有操作被提交(Commit) ,数据库就会恢复到一致的状态。

通俗的讲,在一个数据库事务中的一个或多个SQL操作,要么都执行成功,要么都执行失败

数据库事务在确保多个操作同时执行时数据库的一致性方面非常重要。同时,它还提供了一种恢复由于操作失败或误操作导致数据更改的方法。

MySQL及其事务支持概述

MySQL数据库支持通过提供相关语句的形式来实现数据库事务。

MySQL支持以下内置操作语句:

START TRANSACTION / BEGIN:触发事务的开始。

COMMIT:提交事务,使得对数据库产生的修改变为永久性。

可以通过以下语句设置数据库自动提交更改:

SET autocommit = 1;

SET:用于设置事务提交方式,可以启用事务的自动提交,也可以禁用自动提交。当禁止自动提交时,只有执行COMMIT语句后操作才会提交。

/*禁用自动提交*/
SET autocommit = 0;
/*或者*/
SET autocommit = OFF;
​
/*启用自动提交每一个操作*/
SET autocommit = 1;
/*或者*/
SET autocommit = ON;

ROLLBACK:可用于撤销对数据库所做的更改,从而将数据库返回到操作之前的状态(最近的提交状态)。

事务的ACID特性

ACID表示原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability) 。我们来逐个了解每个特性在事务中的含义。

原子性(Atomicity)

原子性意味着在数据库事务中发生的所有更改会被视为一个整体。这意味着在试图修改数据库时,所有更改要么同时发生,要么完全不发生。

就好比你和你的团队在构建一个应用程序。如果一个人写了一行代码,然后另一人删除了这一行代码,就好像什么都没有发生过。但如果每个人都添加了不同的代码,而且没有人删除代码,那么代码库就会逐渐变大。

一致性(Consistency)

一致性表示数据库中存储的数据始终处于有效和一致的状态。例如,如果数据库包含任何约束(如主键、外键等),则这些数据必须遵循相关约束规则。

举个例子,假设某个表有一个规则,规定特定列必须是整数值。一致性确保这些规则始终得到遵守,插入到该列中的数据只能是整型数据类型。

隔离性(Isolation)

隔离性是指多个事务可以在不互相干扰的情况下执行。事务的隔离级别决定了一个事务所做的更改对其他事务的可见性。

MySQL支持以下隔离级别:

  1. READ UNCOMMITTED:在这个隔离级别(最低级别),一个事务可以读取其他事务尚未提交的数据。这意味着,其他事务可以修改当前事务正在读取的数据,但这些更改可能直到操作完成后才可见。
  2. READ COMMITTED:在次低的隔离级别下,一个事务只能读取其他事务已经提交的数据。其他事务可以修改当前事务正在读取的数据,但这些更改要等到修改后的事务提交后才会可见。
  3. REPEATABLE READ:这是更高级的隔离级别。在此级别,一个事务只能读取其他事务已经提交的数据,且会限制其他事务修改当前事务正在读取的数据。这意味着,即使其他事务提交了更改,如果某个事务再次执行SELECT语句,它会依旧看到同一数据。
  4. SERIALIZABLE:这是最高的隔离级别。在此级别,一个事务只能读取其他事务已经提交的数据,并且防止其他事务修改该事务所读取的数据,以及添加新行(这些新行对当前事务不可见)。

默认情况下,MySQL使用READ COMMITTED隔离级别。另外,可以通过SET TRANSACTION ISOLATION LEVEL语句来改变隔离级别。

持久性(Durability)

持久性确保即使发生意外情况(例如故障或断电),事务的更改也会保存在数据库中。一旦事务被提交,其更改必须永久存储。

MySQL通过写前日志(Write-Ahead Logging, WAL) 机制保证持久性。这种技术在对数据库进行修改之前,会先将事务日志写入磁盘。

该日志充当数据库的“路线图”,包含将在意外系统故障时如何重新进行更改的信息。因此数据库可以从日志中恢复,并重放事务中所做的更改,以确保数据一致性。

需要注意的是,虽然写前日志可能影响性能,但能保证数据安全却是值得付出的代价。

MySQL事务中的锁和并发控制

锁定是为了防止竞争条件的一种技术。竞争条件指的是多个事务尝试同时访问相同数据的情况。

MySQL使用以下几种锁来控制事务中的数据访问:

  1. 共享锁(Shared Locks) :允许多个事务同时读取相同数据,但禁止任何事务对数据进行修改。
  2. 独占锁(Exclusive Locks) :防止不同事务同时读取或修改相同数据。
  3. 意向锁(Intent Locks) :用于标志一个事务计划读取或写入某部分数据。
  4. 行级锁(Row-level Locks) :允许事务仅锁定它需要访问的特定行,而不是锁定整个表。

并发是允许多个事务同时运行,并且不会干扰彼此数据的方法。

MySQL使用多版本并发控制(MVCC, Multi-Version Concurrency Control) 机制,允许多个事务同时读取和写入相同的数据而不会冲突。

这如何实现呢?每个事务在开始时会“捕获”将要修改的数据,并将其更改写入完全不同的版本,这样其他事务可以继续使用原始版本的数据,不会发生冲突。

要实现高并发,务必保持事务尽可能短,并避免长期运行的事务,以免长时间占用锁。

如何在MySQL中创建与使用事务

进行事务操作的第一步是通过START TRANSACTION语句启动一个事务。示例如下:

START TRANSACTION;
    INSERT INTO users (name, email) VALUES (\'师兄奇谈\', \'shixiongqitan@example.com\');
    UPDATE accounts SET balance = SUM(balance) WHERE name = \'师兄奇谈\';

在这个例子中,用START TRANSACTION语句开启一个新事务。之后的两个语句 (INSERTUPDATE) 都是在此事务内执行的。

为了使更改永久保存,我们需要通过COMMIT语句提交更改:

START TRANSACTION;
    INSERT INTO users (name, email) VALUES (\'师兄奇谈\', \'shixiongqitan@example.com\');
    UPDATE accounts SET balance = SUM(balance) WHERE name = \'师兄奇谈\';
COMMIT;

如果在事务过程中出现错误,想撤销更改,可以使用ROLLBACK语句。事务会被回滚,插入和更新语句不再执行,数据库数据不会发生改变。

START TRANSACTION;
    INSERT INTO users (name, email) VALUES (\'师兄奇谈\', \'shixiongqitan@example.com\');
    UPDATE accounts SET balance = SUM(balance) WHERE user_id=15;
ROLLBACK;

如何在MySQL事务中使用InnoDB存储引擎

InnoDB是MySQL的一个存储引擎,提供了许多可提升数据库性能的功能,例如支持组装和执行多个SQL语句、加密数据、创建/删除索引而不影响数据库性能、良好的CPU及大数据处理能力等等。

要在MySQL中使用InnoDB进行事务操作,需要确保表使用的是InnoDB存储引擎。可以通过运行下面的查询来检查:

SHOW TABLE STATUS FROM your_database_name;

可以通过修改my.cnf配置文件设置默认存储引擎为InnoDB,或者运行以下命令:

SET storage_engine=InnoDB;

如何处理事务中的错误和异常

在事务中处理错误和异常至关重要。处理错误的一种常见方法是在MySQL中使用SIGNALRESIGNAL语句,并结合异常处理。

以下是用TRY-CATCH结构处理事务异常的一个示例:

START TRANSACTION;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
    ROLLBACK;
UPDATE accounts SET balance = 5000 WHERE user_id = 1;
UPDATE accounts SET balance = 1000 WHERE user_id = 2;
IF (SELECT balance FROM accounts WHERE user_id = 1) < 0 THEN
    SIGNAL SQLSTATE \'45000\' SET MESSAGE_TEXT = \'Insufficient balance\';
END IF;
COMMIT;

如果在事务中发生了异常,将使用ROLLBACK撤销事务内的所有更改。SIGNAL语句可以用于在事务中自定义异常消息。

一旦事务内发生异常,不管是否处理,事务中的所有更改都会被回滚。

如何在MySQL事务中使用保存点(Savepoints)

在事务中使用SAVEPOINT语句可以设置保存点(savepoint) ,以允许事务回滚到特定的时间点,而不是回滚整个事务。

例如:

START TRANSACTION;
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = 5000 WHERE user_id = 1;
UPDATE accounts SET balance = 1000 WHERE user_id = 2;
IF (SELECT balance FROM accounts WHERE user_id = 1) < 0 THEN
    ROLLBACK TO SAVEPOINT my_savepoint;
END IF;
COMMIT;

SAVEPOINT语句定义了一个命名为my_savepoint的保存点。如果在事务中捕获到异常,可以用ROLLBACK TO SAVEPOINT my_savepoint撤销保存点后的更改,而保留保存点之前的更改。

小结

这篇文章我们从整体上介绍了什么是数据库事务,数据库事务的ACID特征,以及在事务中涉及到的并发锁、MVCC等基础概念,最后通过具体的案例说明了如何开启和回滚事务。这篇文章只是整体的概述,在后续的文章中,我们会针对上述的内容详细展开讲解,记得持续关注。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 开发教程 MySQL的数据库事务、ACID特性以及实战案例 https://www.zuozi.net/3460.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务