欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 【Mysql】事务

【Mysql】事务

2025/2/25 19:29:27 来源:https://blog.csdn.net/2303_77535762/article/details/145836363  浏览:    关键词:【Mysql】事务

【Mysql】事务

  • 一、事务的概念
  • 二、事务的特性(ACID)
      • 2.1 原子性(Atomicity)
      • 2.2 一致性(Consistency)
      • 2.3 隔离性(Isolation)
      • 2.4 持久性(Durability)
  • 三、为什么使用事务
  • 四、使用事务
      • 4.1 语法
      • 4.2 语法的运用
        • 开启一个事务,执行修改后回滚
        • 开启一个事务,提交修改后回滚
      • 4.3 保存点
      • 4.4 自动/手动提交
  • 五、事务的隔离级别
      • 5.1 查看和设置隔离级别
      • 5.2 READ UNCOMMITTED(读未提交)
        • 存在问题
      • 5.3 READ COMMITTED(读已提交)
        • 存在问题
      • 5.4 REPEATABLE READ(可重复读)
        • 存在问题
      • 5.5 SERIALIZABLE(串行化)
        • 存在问题
      • 5.6 总结四大隔离级别

一、事务的概念

事务是一组逻辑上相关的数据库操作,这些操作要么全部成功提交(commit),要么全部回滚(rollback),以保证数据库的完整性。

二、事务的特性(ACID)

2.1 原子性(Atomicity)

原子性是指事务中的所有操作要么全部成功,要么全部失败。如果事务中的某个操作失败,整个事务都会被回滚到初始状态。比如:假设账户A给账户B转账,如果账户A转账成功(账户A已经扣款成功),但是账户B接受失败(账户B加款失败),则整个事务就会回滚,账户A和账户B就会回滚到事务之前(两个账户金额都没发生改变)。

2.2 一致性(Consistency)

一致性是指事务执行前后,数据库必须处于一致的状态。事务完成后,数据应满足所有完整性约束。比如:账户A给账户B转账,账户A转账,账户B只能加款成功。

  • 事务开始前,数据库中的数据必须保持一致性
  • 事务正在进行中,数据可能不处于一致性
  • 事务结束后,数据必须又处于一致性

2.3 隔离性(Isolation)

隔离性是指多个事务并发执行时,每个事务都好像在独立运行,互不干扰。MySQL通过事务隔离级别来控制并发事务之间的可见性。

MySQL支持以下隔离级别(从低到高):

  • READ UNCOMMITTED(读未提交)
  • READ COMMITTED(读已提交)
  • REPEATABLE READ(可重复读)
  • SERIALIZABLE(串行化)

下面会单独给大家详细介绍一遍隔离级别!!!

2.4 持久性(Durability)

  • 持久性是指事务一旦提交,其对数据库的更改将永久生效,即使系统发生故障也不会丢失。
  • 在MySQL中,事务提交后,数据会被写入磁盘,确保不会因系统崩溃而丢失。

三、为什么使用事务

事务是数据库系统中不可或缺的机制,它通过ACID特性确保了数据操作的完整性、一致性和可靠性。使用事务可以简化复杂业务逻辑的管理,支持并发操作,提高系统的可维护性,并满足各种业务场景对数据一致性的严格要求。因此,事务在现代数据库应用中被广泛使用。

MySQL在5.0版本之前默认不支持事务,因为其默认存储引擎MyISAM不支持事务功能。从MySQL 5.0开始,通过引入InnoDB存储引擎,MySQL开始支持事务,并且从5.1版本开始,InnoDB成为默认存储引擎。

四、使用事务

通过show engines; 查看支持事务的存储引擎。
在这里插入图片描述

4.1 语法

开启一个新事务:

START TRANSACTION;begin;

提交当前事务,并对事务进行持久化保存:

commit;

回滚当前事务,取消对数据的修改:

rollback;

无论提交还是回滚,当前事务就会关闭!!!

4.2 语法的运用

首先先创建一个表:

create table account(
id bigint primary key auto_increment,
name varchar(255),
balance decimal(10,2) );

并且给里面插入两个数据:

INSERT INTO account(`name`, balance) VALUES('张三', 1000);
INSERT INTO account(`name`, balance) VALUES('李四', 1000);
select * from account;

在这里插入图片描述

开启一个事务,执行修改后回滚

将张三的balance减少100,李四的balance增加100。
在这里插入图片描述
代码:

 start transaction;update account set balance =balance -100 where name = '张三';update account set balance =balance +100 where name = '李四';select * from account;rollback;select * from account;
开启一个事务,提交修改后回滚

将张三的balance减少100,李四的balance增加100。
在这里插入图片描述
代码:

begin;
update account set balance =balance -100 where name = '张三';
update account set balance =balance +100 where name = '李四';
commit;
rollback;
select * from account;

4.3 保存点

语法:
设置保存点:

SAVEPOINT savepoint_name;

撤销保存点:

RELEASE SAVEPOINT savepoint_name;

一张截图截不下,体谅一哈,谢谢!
在这里插入图片描述

在这里插入图片描述
这里发现我们设置了一个保存点savepoint1,然后我们通过 rollback to savepoint1;返回到保存点savepoiny1;如果使用rollback,则直接返回到事务开始。
在这里插入图片描述

4.4 自动/手动提交

默认情况下,MySQL是⾃动提交事务的,也就是说我们执⾏的每个修改操作,⽐如插⼊、更新和删
除,都会⾃动开启⼀个事务并在语句执⾏完成之后⾃动提交,发⽣异常时⾃动回滚。

查看当前事务是否是自动提交:

SHOW VARIABLES LIKE 'autocommit';
  • ON:表示自动提交模式已启用。
  • OFF:表示自动提交模式已禁用。
SELECT @@autocommit;
  • 1:表示自动提交模式已启用。
  • 0:表示自动提交模式已禁用。

通过以下sql语句可以设置自动/手动提交:

SET autocommit = 1;  -- 启用自动提交
SET autocommit = 0;  -- 禁用自动提交
SET SESSION autocommit = ON;  -- 启用自动提交
SET SESSION autocommit = OFF; -- 禁用自动提交

SELECT @@autocommit; 为例:
在这里插入图片描述

自动提交:

-- 启用自动提交
SET autocommit = 1;
-- 从张三扣款
UPDATE account SET balance = balance - 100 WHERE name = '张三';
-- 向李四加款
UPDATE account SET balance = balance + 100 WHERE name = '李四';

结果:每条UPDATE语句独立提交。如果第一条成功,第二条失败,账户1的余额会被修改,而账户2的余额不会被修改。

手动提交:

-- 禁用自动提交
SET autocommit = 0;
-- 开始事务
START TRANSACTION;
-- 从张三扣款
UPDATE account SET balance = balance - 100 WHERE name = '张三';
-- 向李四加款
UPDATE account SET balance = balance + 100 WHERE name = '李四';
-- 检查操作是否成功
-- 如果成功,提交事务
COMMIT;
-- 如果失败,回滚事务
-- ROLLBACK;

结果:两条UPDATE语句作为一个整体提交。如果第一条成功,第二条失败,整个事务会回滚,两条语句都不会生效。

但是当自己在Mysql上实验发现第二条数据出现错误,第一条数据还是执行了!这是因为MySQL的事务的提交行为错误处理机制 的特点:
Mysql的错误处理机制:

MySQL在执行事务时,对于某些类型的错误(如语法错误、约束冲突等),并不会自动回滚整个事务,而是只终止当前的失败语句。这意味着,如果事务中的某个语句因为语法错误而失败,MySQL不会自动回滚之前已经成功执行的语句。

Mysql的事务的提交行为:

需要在应用程序中显式捕获错误并执行 ROLLBACK。

了解自动和手动提交可以看下此篇博客!!!(如有侵权,请联系我,必删!!!)
这里是对上面博客的自我总结:

手动提交:假设,我们将事务提交设置为手动,用户A修改了一条数据,此时用户B通过查询可以查到数据,但此时不是永久的保存。当用户A崩溃,用户B就不能查到数据。

注意:

如果开启了事务start transaction;或begin;都需要commit;才能永久保存数据,这与SET autocommit
无关系。

五、事务的隔离级别

在这里插入图片描述

5.1 查看和设置隔离级别

查看隔离级别:

# 全局作⽤域
SELECT @@GLOBAL.transaction_isolation;
# 会话作⽤域
SELECT @@SESSION.transaction_isolation;

设置隔离级别:

# 设置全局事务隔离级别为串行化,后续所有事务生效,不影响当前事务
# 方式一
SET GLOBAL transaction_isolation = 'SERIALIZABLE';
# 方式二
SET @@GLOBAL.transaction_isolation='SERIALIZABLE';
# 设置会话事务隔离级别为串行化,当前会话后续的所有事务⽣效,不影响当前事务,可以在任何时候执行
# 方式一
SET SESSION transaction_isolation = 'REPEATABLE-READ';
# 方式二 
SET @@SESSION.transaction_isolation='REPEATABLE-READ';
# 如果不指定任何作⽤域,设置只针对下⼀个事务,随后的事务恢复之前的隔离级别
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

在这里插入图片描述

5.2 READ UNCOMMITTED(读未提交)

存在问题

READ UNCOMMITTED(读未提交):事务A对数据进行修改,事务B访问事务A还没提交的数据,这种情况就是“ 脏读 ”。 事务B访问了事务A rollback数据

5.3 READ COMMITTED(读已提交)

存在问题

READ COMMITTED(读已提交):事务A第一次查询了某条记录,事务B对这条记录进行了修改并提交了,当事务A再次查询这条记录的时候,返现与第一次查询的结果不一样,这个现象叫做“ 不可重复复 ”。

5.4 REPEATABLE READ(可重复读)

存在问题

REPEATABLE READ(可重复读):事务A第一次查询了某个结果集,第二次查询得到的结果集与第一次不同,这种现象就叫“ 幻读 ”。两次查询的结果集不同

5.5 SERIALIZABLE(串行化)

解决了所有数据安全问题,所有事务都是一个挨一个的执行,一个事务必须等上一个事务执行完才执行。

存在问题

REPEATABLE READ(可重复读):性能开销大,因为锁竞争可能导致并发性能下降。

5.6 总结四大隔离级别

不可重复读:针对一条数据。
幻读:针对的是一个结果集。
举个例子:比如一个压缩包中包含多个文件,不可重复读:修改文件内容;幻读:修改压缩包内容(新加一个文件)。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词