从零开始学习MySQL 事务处理

2024-05-11 12:12

本文主要是介绍从零开始学习MySQL 事务处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 事务处理与ACID特性

事务是数据库操作的基本单元,它确保一组操作要么全部成功,要么全部失败,以此来维护数据库的一致性。这四个字母缩写ACID代表了事务的四大特性:

原子性(Atomicity)**:事务被视为不可分割的最小工作单元,事务中的所有操作要么全部执行,要么全部不执行。
一致性(Consistency)**:事务执行前后,数据库的状态保持合法,即符合所有的预定义规则。
隔离性(Isolation)**:并发执行的事务之间互不影响,仿佛是在一个个独立的环境中执行。
持久性(Durability)**:一旦事务被提交,其效果就会永久保存在数据库中,即使系统发生故障也不会丢失。

下面通过几个案例来展示如何在MySQL中使用事务处理及不同隔离级别的影响。

# 基础事务处理案例

假设我们要从一个账户转账到另一个账户,需要两个操作:从账户A减去金额,向账户B增加相同的金额。这两个操作必须在一个事务中执行,以确保数据的一致性。

```sql

START TRANSACTION;

-- 从账户A扣款

UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

-- 向账户B加款

UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

-- 提交事务

COMMIT;


```

如果在执行完第一个`UPDATE`后,程序崩溃或遇到错误,由于没有执行`COMMIT`,事务中的所有操作都会被回滚,从而保证了数据的一致性。

# 隔离级别的演示

MySQL支持四种事务隔离级别:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ,InnoDB的默认级别)和串行化(SERIALIZABLE)。不同的隔离级别会影响事务并发执行时的行为。

## 读未提交(READ UNCOMMITTED)

这种隔离级别下,一个事务可以看到其他事务未提交的更改。

```sql

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

-- 在一个事务中更改但未提交

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

-- 在另一个事务中读取未提交的更改

START TRANSACTION;
SELECT balance FROM accounts WHERE account_id = 1;


```

## 读已提交(READ COMMITTED)

在此隔离级别下,事务只能看到已提交的更改。

```sql

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 事务1提交更改

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
COMMIT;

-- 事务2能看到已提交的更改

START TRANSACTION;
SELECT balance FROM accounts WHERE account_id = 1;


```

## 可重复读(REPEATABLE READ)

这是InnoDB的默认隔离级别,保证了在同一个事务中多次读取同一数据的结果是一致的,即使其他事务已经修改并提交了该数据。

```sql

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 事务1读取余额

START TRANSACTION;
SELECT balance FROM accounts WHERE account_id = 1;

-- 事务2更改余额并提交

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
COMMIT;

-- 事务1再次读取余额,结果不变

SELECT balance FROM accounts WHERE account_id = 1;


```

## 串行化(SERIALIZABLE)

最高隔离级别,通过锁定读取的行来避免并发冲突,相当于顺序执行事务。

```sql

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 事务1读取余额

START TRANSACTION;
SELECT balance FROM accounts WHERE account_id = 1;

-- 事务2尝试更新,但会被阻塞直到事务1结束

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;


```

通过这些案例,我们可以直观地看到不同隔离级别下事务行为的差异,以及它们如何影响数据库的一致性和并发性能。在实际应用中,应根据业务需求选择最合适的隔离级别。

 

Demo1:银行转账

想象一下,你正在使用手机银行应用给朋友转账。这个过程涉及两个关键操作:从你的账户扣除一定金额,同时在你朋友的账户上增加相同金额。为了确保整个过程的准确无误,银行系统就需要使用事务来处理这笔转账操作。

#### 场景设定:

- 你的账户(Account A)余额为500元。
- 你朋友的账户(Account B)余额为300元。
- 你想转账200元给朋友。

#### 无事务处理的情况(想象中的灾难):

如果银行系统没有使用事务,转账可能这样进行:
1. 银行系统从Account A中减去了200元,此时你的账户余额变为300元。
2. 就在这个时候,突然停电了或者系统出现了故障,导致给Account B增加200元的操作没有完成。

结果:你的钱减少了,而你朋友并没有收到钱,这就是一个典型的不一致状态,显然不符合我们的预期。

#### 使用事务处理的情况(安全可靠):

现在,让我们看看事务是如何确保操作的完整性的:

1. **开始事务**:银行系统启动一个事务,准备执行转账操作。
   
   ```sql

   START TRANSACTION;


   ```

2. **扣款操作**:从你的账户减去200元。
   
   ```sql
 

  UPDATE accounts SET balance = balance - 200 WHERE account_id = 'A';


   ```

3. **加款操作**:增加你朋友账户的金额。
   
   ```sql
 

  UPDATE accounts SET balance = balance + 200 WHERE account_id = 'B';


   ```

4. **提交事务**:如果上述两步都成功完成,银行系统提交事务,所有更改永久保存。
   
   ```sql
 

 COMMIT;


   ```

5. **异常处理**:但如果在执行上述操作的过程中发生了任何错误(比如系统故障),事务管理器会检测到这一情况,并执行:
   
   ```sql

   ROLLBACK;


   ```
   这样,之前对Account A的扣款操作会被撤销,账户余额回到500元,就像转账从未发生过一样,保证了数据的完整性。

通过这个例子,我们可以清晰地理解事务如何确保数据的一致性,即使在复杂的操作序列中也能保证“要么全做,要么全不做”的原则,这对于涉及金钱交易、库存管理等敏感操作的系统至关重要。

 Demo2:图书馆借阅系统中的事务处理

设想一个图书馆管理系统,其中涉及图书的借出和归还操作。这个过程同样需要事务来确保数据的准确性和一致性。

# 场景描述:

- 图书馆有《编程珠玑》这本书,当前库存为1本。
- 用户小王想要借阅这本书。

# 借书过程的事务处理:

1. 开始事务:系统启动事务,准备记录借书操作。

   ```sql
   

START TRANSACTION;


   ```

2. 检查库存:确认《编程珠玑》是否有可供借阅的副本。
   
   ```sql
 

  SELECT stock FROM books WHERE title = '编程珠玑' AND available = true;


   ```

3. 更新库存:如果书籍可用,则减少书籍的可用库存,并记录小王借阅的信息。
   
   ```sql

   UPDATE books SET available = false WHERE title = '编程珠玑';INSERT INTO borrow_records (book_title, borrower, borrow_date) VALUES ('编程珠玑', '小王', NOW());


   ```

4. 提交事务:如果上述操作都成功,事务提交,借书操作完成。
   
   ```sql
 

 COMMIT;


   ```

5. 异常处理:如果在借书过程中出现任何问题,比如网络中断、数据库错误等,事务会自动回滚,确保数据的一致性。
   
   ```sql
   

ROLLBACK;


   ```

# 归还过程的事务处理:

当小王归还《编程珠玑》时,也需要通过事务确保操作的原子性和一致性:

1. 开始事务:同借书操作一样,先启动事务。

2. 更新记录:标记书籍为可借状态,并记录归还时间。
   
   ```sql
   

UPDATE books SET available = true WHERE title = '编程珠玑';
UPDATE borrow_records SET return_date = NOW() WHERE book_title = '编程珠玑' AND borrower = '小王' AND return_date IS NULL;


   ```

3. 提交事务:操作成功后提交事务,完成归还流程。

4. 异常处理:遇到错误时回滚事务,确保书籍状态和借阅记录的准确性。

通过这些例子,我们可以看到,无论是银行转账还是图书馆借阅系统,事务处理都是确保数据一致性和完整性的关键机制。在涉及多个数据库操作的情境下,事务能够保证数据的一致性和业务逻辑的正确执行,即使在复杂的系统交互中也能保持数据的准确无误。

 

 更多实例:在线购物车结算过程中的事务处理

设想一个电商平台,用户将商品加入购物车后,决定一次性结算多个商品。这个过程中,涉及到从库存中减少已购买商品的数量,并更新订单信息,同样需要事务来确保操作的原子性和一致性。

# 场景描述:

- 用户张三的购物车中有三件商品:商品A(库存10)、商品B(库存5)、商品C(库存2)。
- 张三决定购买商品A 2件,商品B 3件,商品C 1件。

# 结算过程的事务处理:

1. 开始事务:系统启动事务,准备处理订单创建及库存更新。

   ```sql
   

START TRANSACTION;


   ```

2. 检查库存:验证购物车中每种商品的购买数量是否小于等于现有库存。
   
   ```sql
   

SELECT stock FROM products WHERE product_id IN ('A', 'B', 'C') AND stock >= (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = products.product_id);


   ```

3. 更新库存:如果所有商品的库存都满足购买需求,减少相应商品的库存数量。
   
   ```sql
   

UPDATE products SET stock = stock - (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = 'A') WHERE product_id = 'A';
UPDATE products SET stock = stock - (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = 'B') WHERE product_id = 'B';
UPDATE products SET stock = stock - (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = 'C') WHERE product_id = 'C';


   ```

4. 创建订单:记录订单信息,包括用户信息、商品详情、购买数量等。
   
   ```sql

INSERT INTO orders (user_id, product_id, quantity, order_date) VALUES ('张三', 'A', (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = 'A'), NOW()), ('张三', 'B', (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = 'B'), NOW()), ('张三', 'C', (SELECT quantity FROM cart WHERE user_id = '张三' AND product_id = 'C'), NOW());


   ```

5. 清空购物车:完成购买后,清空用户购物车中已结算的商品。
   
   ```sql
   

DELETE FROM cart WHERE user_id = '张三' AND product_id IN ('A', 'B', 'C');


   ```

6. 提交事务:所有操作成功后,提交事务,完成结算流程。
   
   ```sql
 

 COMMIT;


   ```

7. 异常处理:如果在结算过程中有任何问题,比如某个商品库存不足,系统会捕获错误并回滚事务,保证数据库状态不变,避免了部分商品被错误减少库存而订单未创建的情况。

通过这个例子,我们可以看到事务在电子商务平台中的重要作用,它确保了库存的精确管理、订单的准确生成以及购物车状态的一致性,即便在面对复杂且并发的用户操作时,也能维持系统的稳定和数据的准确。

 

 

 

这篇关于从零开始学习MySQL 事务处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/979496

相关文章

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

Mac电脑如何通过 IntelliJ IDEA 远程连接 MySQL

《Mac电脑如何通过IntelliJIDEA远程连接MySQL》本文详解Mac通过IntelliJIDEA远程连接MySQL的步骤,本文通过图文并茂的形式给大家介绍的非常详细,感兴趣的朋友跟... 目录MAC电脑通过 IntelliJ IDEA 远程连接 mysql 的详细教程一、前缀条件确认二、打开 ID

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum