公司动态

MySQL中的事务(如果想知道MYSQL中有关事务的知识,那么只看这一篇就足够了!)

📅 2026/8/28 1:10:45
MySQL中的事务(如果想知道MYSQL中有关事务的知识,那么只看这一篇就足够了!)
前言事务管理是数据库确保数据一致性和可靠性的核心机制通过将一组操作作为一个整体执行事务要么完全成功要么完全失败避免了数据不一致的问题在多用户并发环境中事务隔离级别决定了不同事务的交互方式影响系统的性能和一致性。* * 这里是的BLOG 想要了解更多内容可以访问我的主页-CSDN博客在正式开始讲解之前先让我们看一下本文大致的讲解内容目录1.事务的初识???1事务的概念? ? ? ? 2事务的基本操作? ? ? ? 3事务的回滚与保存点2.ACID 特性? ? ? ? 1原子性Atomicity? ? ? ? 2一致性Consistency? ? ? ? 3隔离性Isolation? ? ? ? 4持久性Durability3.事务隔离级别? ? ? ? 1读未提交? ? ? ? 2读已提交? ? ? ? 3可重复读? ? ? ? 4串行化SERIALIZABLE4.自动提交与手动提交模式? ? ? ? 1自动提交模式?? ? ? ? 2手动提交模式*1.事务的初识-------### 1事务的概念在开始学习MySQL中的事务之前先让我们来了解一下什么是MySQL中的事务 **事务是将一组 SQL 操作封装为一个整体确保这些操作要么全都成功要么全都失败***事务的主要应用场景大致有资金转账、库存扣减等多个步骤组成的操作保证这些操作能够在出现错误时进行回滚从而确保数据的一致性和完整性。**通过上述的简短描述我们就对MySQL中事务的定义有了初步的了解了那么接下来让我们进一步了解一下MySQL中的事务。### 2事务的基本操作在 MySQL 中事务的控制是通过以下 SQL 语句来实现的 *START TRANSACTION或BEGIN开启事务。 *COMMIT提交事务将所有更改持久化保存。 *ROLLBACK回滚事务撤销对数据的所有修改。例如考虑一个简单的银行转账操作假设要从账户 A 扣款 100 元往账户 B 存款 100 元。我们希望这两个操作要么都成功要么都失败若出现任何问题都应当回滚整个事务。START TRANSACTION; UPDATE accounts SET balance balance - 100 WHERE account_id 1; – 扣款操作 UPDATE accounts SET balance balance 100 WHERE account_id 2; – 存款操作 COMMIT; – 提交事务保存所有更改代码解释 首先启动一个事务然后执行两条 SQL 语句从账户 A 扣款 100 元同时往账户 B 存款 100 元最后通过COMMIT提交事务确保这两个操作成功保存。通过上述的案例我们就大致的了解了MySQL中的事务的基本操作了### 3事务的回滚与保存点回滚是事务中的一个重要特性如果在事务执行过程中遇到错误可以通过 ROLLBACK 将所有更改撤销恢复到事务开始之前的状态除此之外MySQL 还支持使用 保存点来标记事务中的特定位置允许在出现错误时仅回滚到某个特定的保存点而不是完全回滚。 START TRANSACTION; SAVEPOINT savepoint1; – 设置保存点 UPDATE accounts SET balance balance - 100 WHERE account_id 1; – 如果发生错误回滚到保存点 ROLLBACK TO SAVEPOINT savepoint1; COMMIT; – 提交事务代码解释 保存点savepoint1被设置在事务开始后若发生错误事务会回滚到此保存点避免撤销整个事务的所有操作。至此我们就大致的初识了MySQL中的事务的内容了2.ACID 特性---------在学习完了MySQL中的事务的基本概念之后在让我们学习一下ACID 特性ACID 是数据库事务的核心概念它代表了四个基本的属性*原子性Atomicity、一致性Consistency、隔离性Isolation和持久性Durability这四个特性确保了事务的正确性和数据库的稳定性。### 1原子性Atomicity原子性意味着事务中的所有操作要么全部执行成功要么全部执行失败如果事务中的任何操作失败整个事务会被回滚恢复到事务开始之前的状态。****例子——假设我们正在进行一个资金转账操作如果扣款成功但是存款失败整个事务应该回滚确保资金不会丢失以下是实现原子性的代码 START TRANSACTION; UPDATE accounts SET balance balance - 100 WHERE account_id 1; – 扣款操作 UPDATE accounts SET balance balance 100 WHERE account_id 2; – 存款操作 – 如果第二个操作失败整个事务回滚 ROLLBACK; – 恢复到事务开始之前的状态代码解释 如果存款操作由于某些原因失败那么事务会回滚到开始时的状态确保数据不会处于不一致的状态。### 2一致性Consistency一致性意味着事务必须确保数据库的完整性约束得到遵守事务执行前后数据库从一个一致的状态过渡到另一个一致的状态无论事务是否成功完成数据库都应该处于有效的状态。****例子——在银行转账中必须保证在扣款和存款操作之间账户余额的变化始终遵循一定的规则例如账户余额不能为负数。 START TRANSACTION; UPDATE accounts SET balance balance - 100 WHERE account_id 1; – 确保账户余额大于零 IF (SELECT balance FROM accounts WHERE account_id 1) 0 THEN ROLLBACK; – 如果余额不足回滚事务 END IF; UPDATE accounts SET balance balance 100 WHERE account_id 2; COMMIT;代码解释 在进行扣款操作后我们检查账户余额是否足够如果余额不足则回滚事务否则继续执行存款操作这样可以确保数据库的一致性。### 3隔离性Isolation隔离性保证了事务的执行不受其他事务的干扰即使多个事务同时执行它们的操作互不影响为了实现隔离性数据库管理系统提供了不同的事务隔离级别每个隔离级别在并发性能与数据一致性之间做了不同的权衡。MySQL 支持四种事务隔离级别 1.READ UNCOMMITTED读未提交事务可以读取其他事务未提交的数据可能会发生脏读。 2.READ COMMITTED读已提交事务只能读取已提交的数据避免脏读但仍然可能发生不可重复读。 3.REPEATABLE READ可重复读事务中的所有查询都能读取到一致的数据避免了不可重复读。 4.SERIALIZABLE串行化事务按照顺序执行确保没有并发问题但性能最低。例子——在 MySQL 中我们可以设置事务的隔离级别以下代码展示了如何设置事务的隔离级别 – 查看当前事务隔离级别 SELECT global.tx_isolation; – 设置事务隔离级别为 REPEATABLE READ SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION; SELECT balance FROM accounts WHERE account_id 1; – 读取账户余额 COMMIT;代码解释 我们设置了事务的隔离级别为 REPEATABLE READ这意味着事务执行过程中所有的读取操作将看到相同的数据从而避免了不可重复读的问题。### 4持久性Durability持久性确保了事务一旦提交对数据的修改将永久写入数据库即使系统发生崩溃或其他故障数据也不会丢失。**例子START TRANSACTION; UPDATE accounts SET balance balance - 100 WHERE account_id 1; COMMIT; – 提交事务修改会被永久保存代码解释 即使在提交后系统崩溃了数据库仍然会从日志文件中恢复到一致状态确保资金的变动不会丢失。这样我们就学习完了MySQL中的.ACID 特性了3.事务隔离级别--------接下来在让我们学习一下事务隔离级别我们知道MySQL 使用InnoDB存储引擎支持四种事务隔离级别分别为READ UNCOMMITTED读未提交、READ COMMITTED读已提交、REPEATABLE READ可重复读和 SERIALIZABLE串行化这些隔离级别通过锁机制和多版本并发控制MVCC来实现不同的隔离级别会影响数据的一致性和并发性能。### 1读未提交读未提交是最低的隔离级别事务 A 可以读取事务 B 中尚未提交的数据由于事务 A 读取的数据可能是一个未提交的更改因此会导致所谓的 脏读Dirty Read。 *脏读事务 A 在事务 B 提交前读取了事务 B 对某个数据的修改如果事务 B 回滚事务 A 读取到的数据就是无效的。 *优点性能最优适合对数据一致性要求不高的场景。 *缺点可能导致数据不一致极易引发逻辑错误。例子—— 假设有两个事务同时进行一个事务正在更新数据而另一个事务可以读取这个未提交的更新。 – 事务 A SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION; UPDATE accounts SET balance balance - 100 WHERE account_id 1; – 事务 B START TRANSACTION; SELECT balance FROM accounts WHERE account_id 1; – 读取事务 A 未提交的数据 COMMIT;代码解释 事务 B 读取到了事务 A 尚未提交的更改。如果事务 A 最终回滚事务 B 读取的数据就是无效的产生了脏读问题。### 2读已提交读已提交隔离级别解决了脏读问题确保事务只能读取已提交的数据。但它仍然允许在同一个事务内多次查询返回不同结果产生 不可重复读Non-repeatable Read问题。 *不可重复读在同一个事务中多次读取同一数据但每次读取的结果不同因为其他事务可能已经提交了更改。 *优点避免了脏读保证了数据的一致性。 *缺点容易产生不可重复读问题。例子——在READ COMMITTED隔离级别下事务 A 在同一事务内的两次查询结果可能不同。 – 事务 A SET TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION; SELECT balance FROM accounts WHERE account_id 1; – 第一次查询 – 事务 B START TRANSACTION; UPDATE accounts SET balance balance - 50 WHERE account_id 1; COMMIT; – 事务 B 提交 – 事务 A SELECT balance FROM accounts WHERE account_id 1; – 第二次查询结果不同 COMMIT;代码解释 事务 A 的第二次查询结果与第一次查询的结果不同因为事务 B 在事务 A 的查询之间提交了更改。### 3可重复读可重复读隔离级别解决了不可重复读问题确保在同一个事务中所有的查询操作返回的结果始终一致。InnoDB 存储引擎使用多版本并发控制MVCC机制来实现这一点。 *可重复读事务内的所有读取操作始终返回相同的数据即使其他事务修改了这些数据。 *幻读在REPEATABLE READ隔离级别下虽然事务 A 在多次读取中得到相同结果但在查询过程中另一个事务可以插入新的记录导致事务 A 查询的范围发生变化这就是幻读问题。 *优点解决了脏读和不可重复读问题。 *缺点仍然可能发生幻读。例子– 事务 A SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION; SELECT balance FROM accounts WHERE account_id 1; – 第一次查询 – 事务 B START TRANSACTION; INSERT INTO accounts (account_id, balance) VALUES (3, 100); – 事务 B 插入新记录 COMMIT; – 事务 A SELECT balance FROM accounts WHERE account_id 1; – 第二次查询可能出现幻读问题 COMMIT;代码解释 虽然事务 A 中的查询结果始终一致但如果事务 B 在事务 A 执行过程中插入了新的记录事务 A 可能会遇到幻读问题即查询的结果集发生了变化。### 4串行化SERIALIZABLE串行化是最严格的事务隔离级别所有事务串行执行互不干扰。它通过强制加锁的方式确保一个事务在执行时其他事务必须等待直到该事务完成这种方式完全解决了所有的并发问题包括脏读、不可重复读和幻读。 *优点完全避免了脏读、不可重复读和幻读问题确保数据的绝对一致性。 *缺点性能最差因为事务需要串行执行严重影响并发性能。例子– 事务 A SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION; SELECT balance FROM accounts WHERE account_id 1; – 第一次查询 – 事务 B START TRANSACTION; UPDATE accounts SET balance balance - 50 WHERE account_id 1; – 事务 B 更新数据 COMMIT; – 事务 A SELECT balance FROM accounts WHERE account_id 1; – 第二次查询结果不会变化 COMMIT;代码解释 事务 A 和事务 B 会串行执行事务 A 在执行期间会被阻塞直到事务 B 完成。至此我们就了解了MySQL中的事务隔离级别了4.自动提交与手动提交模式-------------最后在让我们学习一下自动提交与手动提交模式在 MySQL 中事务默认是自动提交的这意味着每条 SQL 语句执行后都会立即提交然而有时开发者希望控制事务的提交过程这时可以关闭自动提交手动执行事务提交。### 1自动提交模式——默认情况下MySQL 在每个 SQL 语句后都会自动提交事务当然我们也可以设置自动提交事务 – 启用自动提交 SET AUTOCOMMIT 1; ### 2手动提交模式在手动提交模式下事务不会自动提交而是需要通过显式的COMMIT或ROLLBACK来控制。 – 禁用自动提交 SET AUTOCOMMIT 0; START TRANSACTION; UPDATE accounts SET balance balance - 100 WHERE account_id 1; – 手动提交事务 COMMIT; 通过手动提交事务开发者可以更加精细地控制事务的执行确保在复杂操作中的数据一致性。以上就是自动提交与手动提交模式的全部内容了* *以上就是本篇文章全部内容~~