首页 > 数据库 >mysql事务

mysql事务

时间:2024-09-15 19:51:08浏览次数:3  
标签:事务 读取 -- mysql balance id 隔离

MySQL 事务是数据库管理系统 (DBMS) 中的一项关键功能,确保一系列数据库操作作为一个整体被执行,且具有原子性、一致性、隔离性和持久性 (ACID) 的特性。事务处理机制可以帮助开发者确保数据的完整性和一致性,特别是在出现错误或并发操作时。

1. 事务的四大特性 (ACID)

  • 原子性 (Atomicity)
    事务中的所有操作要么全部完成,要么全部不完成。原子性确保了事务的所有操作作为一个不可分割的单元执行。

  • 一致性 (Consistency)
    事务从一个一致状态转换到另一个一致状态,即在事务执行前后,数据库的完整性约束不会被破坏。

  • 隔离性 (Isolation)
    多个事务同时执行时,一个事务的操作不会影响其他事务。隔离性决定了一个事务如何对其他事务的并发执行可见。

  • 持久性 (Durability)
    一旦事务提交,其结果应永久存储在数据库中,即使系统发生崩溃,提交后的数据也不会丢失。

2. MySQL 中的事务控制语句

MySQL 使用 InnoDB 引擎来支持事务处理。常用的事务控制语句包括:

  • START TRANSACTION:显式开启一个事务。
  • COMMIT:提交事务,所有对数据库的修改会永久保存。
  • ROLLBACK:回滚事务,撤销自事务开启以来的所有修改。
  • SAVEPOINT:设置事务的保存点,允许在事务中回滚到特定的保存点。
  • RELEASE SAVEPOINT:删除某个保存点,之后无法再回滚到该保存点。
  • ROLLBACK TO SAVEPOINT:回滚到某个保存点,之后的修改被撤销,但保存点之前的操作不受影响。

3. MySQL 事务的基本使用

3.1 开启事务

通过 START TRANSACTION 开启事务:

START TRANSACTION;
-- 执行一系列操作
INSERT INTO accounts (user_id, balance) VALUES (1, 1000);
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
-- 提交事务
COMMIT;

如果某个操作发生错误,可以通过 ROLLBACK 来回滚整个事务:

START TRANSACTION;
-- 执行操作
INSERT INTO accounts (user_id, balance) VALUES (1, 1000);
-- 出现错误,回滚
ROLLBACK;
3.2 使用保存点

保存点允许你在事务中部分回滚,而不影响之前的操作。

START TRANSACTION;
-- 设置保存点
SAVEPOINT sp1;
INSERT INTO accounts (user_id, balance) VALUES (1, 1000);
-- 设置另一个保存点
SAVEPOINT sp2;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
-- 回滚到 sp1,撤销 sp2 之后的操作
ROLLBACK TO SAVEPOINT sp1;
-- 提交事务
COMMIT;

4. MySQL 事务的隔离级别

事务的隔离性确保多个事务并发执行时不会互相干扰,MySQL 提供了四种隔离级别,不同的隔离级别决定了事务如何处理并发操作的可见性。隔离级别越高,并发性能越低,但数据一致性越强。

MySQL 支持以下四种事务隔离级别:

  1. READ UNCOMMITTED(未提交读)
    允许一个事务读取另一个未提交事务的修改。会导致“脏读”问题。

  2. READ COMMITTED(提交读)
    只允许一个事务读取另一个已经提交的事务修改。避免脏读,但可能导致“不可重复读”问题。

  3. REPEATABLE READ(可重复读)(MySQL 默认的隔离级别)
    保证在同一个事务中多次读取同一数据时,结果一致。避免脏读和不可重复读,但可能导致“幻读”问题。

  4. SERIALIZABLE(可串行化)
    强制事务顺序执行,完全避免并发问题,但性能较差。避免脏读、不可重复读和幻读。

5. 事务隔离级别的配置

  • 查看当前隔离级别

    SELECT @@transaction_isolation;
    
  • 设置全局或会话隔离级别

    • 设置全局隔离级别:

      SET GLOBAL transaction_isolation = 'REPEATABLE READ';
      
    • 设置会话隔离级别:

      SET SESSION transaction_isolation = 'READ COMMITTED';
      

6. 并发事务中的问题

并发事务可能会导致以下几种问题:

  1. 脏读
    事务A读取了事务B修改的未提交数据,如果事务B回滚,事务A读取到的数据就会失效。

  2. 不可重复读
    事务A在两次读取同一数据时,读到不同的结果。事务B在事务A第二次读取之前,修改了该数据并提交。

  3. 幻读
    事务A读取了满足某条件的多行数据,事务B在事务A读取后插入或删除了一些数据,导致事务A再查询时看到不一致的结果。

7. 示例:处理事务的不同隔离级别

假设我们有两个事务:

  • 事务 A 开启时读取一笔数据。
  • 事务 B 在 A 进行读取后修改了该数据并提交。
7.1 READ UNCOMMITTED

事务 A 读取未提交的数据:

-- 事务 B
START TRANSACTION;
UPDATE accounts SET balance = 2000 WHERE user_id = 1;

-- 事务 A(读取事务 B 未提交的数据)
SELECT balance FROM accounts WHERE user_id = 1;

-- 事务 B 回滚
ROLLBACK;

在 READ UNCOMMITTED 隔离级别下,事务 A 能够读取到事务 B 未提交的修改,导致脏读问题。

7.2 REPEATABLE READ(默认隔离级别)

在可重复读隔离级别下,事务 A 能够保证多次读取的数据是一致的:

-- 事务 A
START TRANSACTION;
SELECT balance FROM accounts WHERE user_id = 1;

-- 事务 B
START TRANSACTION;
UPDATE accounts SET balance = 2000 WHERE user_id = 1;
COMMIT;

-- 事务 A 再次读取
SELECT balance FROM accounts WHERE user_id = 1;

-- 事务 A 提交
COMMIT;

在 REPEATABLE READ 下,事务 A 的两次读取会得到相同的数据,即使事务 B 已经提交了修改。

8. 使用案例

在电商系统中,事务常用于处理订单、支付、库存等操作。例如,处理用户购买商品时,库存的扣减和订单生成必须是原子操作,如果扣减库存失败,订单应该回滚。这可以通过事务来保证一致性:

START TRANSACTION;

-- 扣减库存
UPDATE products SET stock = stock - 1 WHERE product_id = 1001 AND stock > 0;

-- 生成订单
INSERT INTO orders (user_id, product_id, amount) VALUES (1, 1001, 1);

COMMIT;

如果库存不足或订单生成失败,整个事务将回滚,确保数据一致性。

总结

MySQL 事务通过 ACID 特性确保了数据库操作的可靠性。不同的隔离级别在性能和数据一致性之间做了权衡,开发者应根据具体场景选择适合的事务隔离级别。在事务处理中,掌握回滚、保存点和并发控制等机制是确保数据一致性和完整性的关键。

标签:事务,读取,--,mysql,balance,id,隔离
From: https://blog.csdn.net/m0_73163793/article/details/142099896

相关文章

  • mySql 添加新用户
    运行以下SQL语句来创建新用户并设置密码:INSERTINTOmysql.user(User,Host,Password)VALUES('用户名','主机名',PASSWORD('密码'));其中,'用户名'为新用户的名称,     '主机名'为允许该用户连接的主机,可以使用通配符'%'表示允许从任何主机连接,    ......
  • 【MySQL】MySQL索引与事务的透析——(超详解)
    前言......
  • mysql数据怎么导入到帝国cms
    将MySQL数据导入到帝国CMS中通常有两种情况:一种是从现有的MySQL数据库导入数据到帝国CMS的新建数据库中,另一种是从帝国CMS的备份文件恢复数据到现有的帝国CMS数据库中。以下是针对这两种情况的具体步骤:从现有MySQL数据库导入数据到帝国CMS方法一:手动迁移数据导出现有数据库:......
  • VPS Ubuntu22.04 安装WordPress 搭建网站 详细全流程(基于Apache+MySQL+PHP)(二)
    VPSUbuntu22.04安装WordPress搭建网站详细全流程(基于Apache+MySQL+PHP)(二)简介在网站处理和网络管理方面,WordPress是用户可以采取的最明智的选择。由于WordPress的巨大优势,它在网页设计师中广受欢迎。统计数据显示,访问量最大的1000个网站中约有35%是WordPress。......
  • MySQL 大表拆分
    概述在实际工作中,在关系数据库(MySQL、PostgreSQL)的单表数据量上亿后,往往会出现查询和分析变慢甚至无法执行统计分析的情况。这时就需要将大表拆分为多个小表,将小表分布在多个数据库上,形成一个数据库集群。这样的话,一条SQL统计语句就可以在多台服务器上并发执行,然后将执行结果汇......
  • 【MySQL】基础部分——DDL,DML,DQL,DCL,函数,约数,多表查询,事务
    个人学习记录,供以后回顾和复习ubuntu下安装使用1.DDL,DML,DQL,DCLDDL数据库表DML增改删DQL条件查询分组查询排序查询分页查询DCL管理用户权限控制2.函数字符串函数数值函数日期函数流程函数3.约束4.多表查询多表关系内连接外连接自连接联合查询union子查询标量子查询......
  • mysql笔记8(多表查询)
    文章目录1.union联合查询可能会用到去重操作2.innerjoin内连接3.leftjoin左连接4.rightjoin右连接5.crossjoin交叉连接6.naturaljoin自然连接naturalleftjoin自然左连接naturalrightjoin自然右连接自然连接的两张表没有同名字段怎么办?7.using......
  • Mysql 面试题总结
    1.Mysql数据库,隔离级别有哪几个?在MySQL数据库中,事务的隔离级别决定了一个事务在执行期间对其他事务可见的数据变化情况。MySQL支持SQL标准定义的四种隔离级别,从低到高依次为:读未提交(READUNCOMMITTED)在该隔离级别下,事务中的修改即使没有提交,对其他事务也是可见的。......
  • 如何解决MySQL + 字段锁表问题|如何优化MySQL DDL操作以减少锁表时间|深入理解MySQL的On
    在日常的数据库操作中,MySQL数据库的表结构修改是不可避免的操作之一。例如,添加新字段是常见的需求之一。然而,在生产环境中对表结构进行更改时,特别是在大数据量的表中,容易出现锁表问题,导致业务系统的性能下降甚至完全卡顿。MySQL在进行表结构修改时会加表级锁,从而影响到其他的查询和......
  • 高级java每日一道面试题-2024年9月12日-架构篇[DDD领域驱动篇]-如何使用领域驱动设计(D
    如果有遗漏,评论区告诉我进行补充面试官:如何使用领域驱动设计(DDD)中的事务脚本模式?我回答:在Java高级面试中,讨论如何使用领域驱动设计(DDD)中的事务脚本模式是一个很好的话题,因为它不仅考察了面试者对DDD原则的理解,还检验了其在实际项目中应用这些原则的能力。事务脚本模......