MySQL数据库事务的学习(有业务场景案例)

一、事务的基本概念

定义:事务是数据库管理系统执行过程中的一个逻辑单位,由一个或多个SQL语句组成,这些语句作为一个整体一起向系统提交,要么全部执行,要么全部不执行。

二、ACID特性详解

1. 原子性(Atomicity)

定义 :事务中的操作要么全部成功,要么全部失败,不会结束在中间某个环节。事务在执行过程中发生错误会被回滚(Rollback)到事务开始前的状态,就像这个事务从未执行过一样。
实现机制:MySQL通过回滚日志(Undo Log)来实现事务的原子性。当事务执行失败时,系统可以利用回滚日志中的数据将事务回滚到事务开始前的状态。

2. 一致性(Consistency)

定义 :事务必须使数据库从一个一致性状态变换到另一个一致性状态。事务开始和结束时,数据库的整体状态应该是一致的,即满足所有的完整性约束。
保证机制:MySQL通过约束(如外键约束、主键约束等)和锁(如行锁、表锁等)机制来确保数据的一致性。

3. 隔离性(Isolation)

定义 :数据库系统提供一定的隔离机制,使得事务在不受外部并发操作干扰的情况下运行,以保证事务的并发正确性。
隔离级别:MySQL支持四种隔离级别,分别是未提交读(READ UNCOMMITTED)、已提交读(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。不同的隔离级别可以解决不同程度的并发问题,但也会带来不同的性能开销。

4. 持久性(Durability)

定义 :一旦事务被提交,它对数据库的修改就是永久性的,即使数据库发生故障也不会丢失。
实现机制:MySQL通过重做日志(Redo Log)来实现事务的持久性。当事务提交时,系统会将事务中对数据库的修改操作记录到重做日志中,并在系统重启时利用这些日志恢复数据。

三、事务的操作流程

开启事务 :使用BEGIN或START TRANSACTION语句显式地开启一个事务,或者将autocommit设置为0(关闭自动提交)。
执行事务操作 :在事务中执行一系列的SQL语句,这些语句要么全部成功,要么全部失败。
提交事务 :如果事务中的所有操作都成功执行,则使用COMMIT语句提交事务,将事务中的修改永久保存到数据库中。
回滚事务:如果事务中的任何操作失败,或者需要撤销已执行的操作,则使用ROLLBACK语句回滚事务,将数据库恢复到事务开始前的状态。

四、事务的并发问题及其解决

在并发环境下,事务之间可能会产生脏读、不可重复读和幻读等问题。MySQL通过不同的事务隔离级别来解决这些问题:

未提交读(READ UNCOMMITTED) :最低的隔离级别,允许读取尚未提交的数据,可能会导致脏读。
已提交读(READ COMMITTED) :允许在事务中读取已经提交的数据,解决了脏读问题,但可能会出现不可重复读和幻读。
可重复读(REPEATABLE READ) :MySQL的默认隔离级别,保证在同一个事务中多次读取同样记录的结果是一致的,解决了脏读和不可重复读问题,但可能会出现幻读。
串行化(SERIALIZABLE):最高的隔离级别,通过强制事务串行执行来避免脏读、不可重复读和幻读问题,但会严重降低并发性能。

五、案例

1.银行转账

场景描述:

在银行系统中,A用户需要向B用户转账1000元。这个操作需要涉及到两个步骤:一是从A用户的账户中扣除1000元,二是向B用户的账户中增加1000元。这两个步骤必须作为一个整体来执行,要么全部成功,要么全部失败,以保证资金的安全和准确。

实现步骤:

开启事务:使用START TRANSACTION或BEGIN语句开启一个事务。
执行转账操作:
从A用户账户扣除1000元:UPDATE accounts SET balance = balance - 1000 WHERE user_id = 'A';
向B用户账户增加1000元:UPDATE accounts SET balance = balance + 1000 WHERE user_id = 'B';
提交事务:如果两个更新操作都成功执行,则使用COMMIT语句提交事务,将更改永久保存到数据库中。
回滚事务:如果在执行过程中遇到任何错误(如余额不足等),则使用ROLLBACK语句回滚事务,撤销之前的所有更改。

2. 电商订单处理

场景描述: 在电商系统中,用户下单并支付成功后,需要生成订单并减少相应商品的库存。这个过程同样需要保证数据的一致性和完整性。

实现步骤:

开启事务:使用START TRANSACTION或BEGIN语句开启一个事务。
执行订单处理操作:
插入订单记录到订单表中:INSERT INTO orders (user_id, product_id, quantity, ...) VALUES (...);
减少商品库存:UPDATE products SET stock = stock - quantity WHERE product_id = ...;
提交事务:如果订单记录和库存更新都成功执行,则使用COMMIT语句提交事务。
回滚事务:如果在执行过程中遇到任何错误(如库存不足、支付失败等),则使用ROLLBACK语句回滚事务。

3. 库存管理系统

场景描述:

在库存管理系统中,当某种商品的库存量低于一定阈值时,需要自动触发补货流程。这个流程可能包括多个步骤,如生成补货单、更新库存状态等。

实现步骤:

开启事务:使用START TRANSACTION或BEGIN语句开启一个事务。
执行补货操作:
检查库存量是否低于阈值。
如果低于阈值,则生成补货单并插入到补货单表中:INSERT INTO reorder_orders (product_id, quantity, ...) VALUES (...);
更新库存状态为待补货:UPDATE products SET status = 'pending_reorder' WHERE product_id = ...;
提交事务:如果所有补货操作都成功执行,则使用COMMIT语句提交事务。
回滚事务:如果在执行过程中遇到任何错误(如补货单生成失败、库存状态更新失败等),则使用ROLLBACK语句回滚事务。

相关推荐
Amctwd4 分钟前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou40 分钟前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh1 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
黄暄1 小时前
初识计算机网络。计算机网络基本概念,分类,性能指标
笔记·学习·计算机网络·考研
梅子酱~2 小时前
Vue 学习随笔系列二十三 -- el-date-picker 组件
前端·vue.js·学习
Alice-YUE2 小时前
【HTML5学习笔记1】html标签(上)
前端·笔记·学习·html·html5
喝醉的小喵2 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
jerry6092 小时前
LLM笔记(五)概率论
人工智能·笔记·学习·概率论
付出不多3 小时前
Linux——mysql主从复制与读写分离
数据库·mysql
初次见面我叫泰隆3 小时前
MySQL——1、数据库基础
数据库·adb