MySQL-事务

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL-事务

🚀事务

事务是数据库管理系统(DBMS)中的一个重要概念,用于确保数据库操作的一致性和完整性。事务是一组数据库操作(例如插入、更新、删除等),这些操作被视为一个不可分割的工作单元,要么全部成功执行,要么全部回滚(撤销)。

在使用事务时,通常需要使用事务控制语句(例如BEGIN、COMMIT和ROLLBACK)来明确地开始、提交或回滚事务。

需要注意的是,事务的使用需要谨慎考虑,并且合理设计事务的边界和范围,以避免潜在的并发问题和性能影响。

举例:

A ------ 100 元

B ------ 100 元

A 给 B 转账100元 那么A的钱就减少100元,B的钱增加100元,这是一组数据库操作,被视为一个不可分割的工作单元,要么同时成功,要么同时失败

解析:

正常情况下,类似转账的操作,可拆分为以下三步

1.查询A账户余额                    

2.A账户余额减少100               A的余额100-100=0        

3.B账户余额增加100               B的余额100+100=200

异常情况下,类似转账的操作,也是这三步,此时在执行第三步时抛出异常

1.查询张三账户余额

2.A账户余额减少100             A的余额100-100=0

3.B账户余额不变                   B的余额100

如何解决上述问题?

我们只需要在业务逻辑执行之前开启事务,执行  完毕后提交事务。如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态。


注意:默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务

🚀事务操作

数据准备:

drop table if exists bank; ---如果存在表bank我们就删去
create table bank(
    id int primary key auto_increment comment '账户ID',
    name varchar(20) comment '账户姓名',
    money double(10,2) comment '账户余额'
) comment '账户表'; 
insert into bank(name, money) values ('沈立聪',5000), ('李佳成',5000);

执行:

🚀未控制事务

测试正常情况

-- 1. 查询沈立聪余额
select * from bank where name = '沈立聪'; 
-- 2. 沈立聪的余额减少2000
update bank set money = money - 2000 where name = '沈立聪'; 
-- 3. 李佳成的余额增加2000
update bank set money = money + 2000 where name = '李佳成';

执行:(数据一致)

测试异常情况

首先将原数据手动恢复一下:

再执行下列语句查看效果

-- 1. 查询沈立聪余额
select * from bank where name = '沈立聪'; 
-- 2. 沈立聪的余额减少2000
update bank set money = money - 2000 where name = '沈立聪'; 
这条不符合语法的语句使绊子...
-- 3. 李佳成的余额增加2000
update bank set money = money + 2000 where name = '李佳成';

执行过程:

我们采用一句不符合语法的句子,中途阻塞一下给李佳成余额增加2000的第三步操作。最终效果如下 (沈立聪2000元扣除,但是李佳成2000元没有加上)

发现前后数据量是不对的

🚀控制事务

✨查看事务状态

你可以使用以下语句来查看当前事务的状态:

SELECT @@autocommit ; --注意只针对当前窗口有效

这将显示当前的自动提交(autocommit)设置,如果它的值为1,表示自动提交已启用;如果为0,表示自动提交已禁用。

执行:

✨设置事务

你可以使用以下语句来设置事务的自动提交选项:

注意:如果你已经将事务的提交方式设置为了手动提交,此时当你在执行任何一个DML语句时,它只是去临时修改了表数据,并没有提交给数据库,要提交给数据库,必须执行commit命令

SET autocommit = 0; -- 禁用自动提交,开启事务

执行:

✨提交事务

一旦你禁用了自动提交,你可以使用以下语句来提交事务:

COMMIT;

✨开启事务

START TRANSACTION 或 BEGIN ;

✨回滚事务

如果在事务执行过程中出现了错误,你可以使用以下语句来回滚事务:

ROLLBACK;

注意:上述的这种方式,我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提交, 此时我们执行的DML语句都不会提交, 需要手动执行commit操作进行提交。

🚀注意事项

在使用事务时,需要注意以下几点:

1.谨慎使用事务:事务应该被精心设计,避免事务范围过大或持续时间过长,以免影响数据库性能和并发性。

2.避免长时间锁定:长时间的事务可能会导致数据库中的行或表被长时间锁定,影响其他事务的执行。因此,应尽量避免长时间的事务操作。

3.异常处理:在事务中应该包含适当的异常处理机制,以便在出现错误时能够回滚事务并进行恰当的处理。

4.保持事务简洁:尽量避免在事务中进行复杂的逻辑或长时间的计算,以免影响其他事务的执行。

5.定时提交:如果可能的话,应该在事务中定期进行提交,而不是等到事务结束才提交,以减小锁定的范围和时间。

6.并发控制:在设计事务时,需要考虑并发控制的问题,避免出现数据不一致或并发冲突的情况。

以上是一些使用事务时需要注意的事项。合理的使用事务可以确保数据库操作的一致性和完整性,但需要注意避免潜在的性能和并发问题。

转账案例:

-- 开启事务
begin ;
-- 1. 查询张三余额
select * from bank where name = '沈立聪'; 
-- 2. 沈立聪的余额减少2000
update bank set money = money - 2000 where name = '沈立聪'; 
-- 3. 李佳成的余额增加2000
update bank set money = money + 2000 where name = '李佳成'; 
-- 如果正常执行完毕, 则提交事务
commit;
-- 如果执行过程中报错, 则执行回滚事务
rollback;

执行:

若执行异常,事务回滚之后

🚀事务四大特性


事务是指一组数据库操作,这些操作要么全部执行成功,要么全部回滚。在数据库中,事务具有四个基本特性,即ACID特性。下面我将对这四个特性进行详细描述:

原子性(Atomicity)

原子性是指一个事务中的所有操作要么全部执行成功,要么全部回滚。如果在事务执行过程中出现任何错误,所有已经执行的操作都将被回滚,数据库状态将恢复到事务开始之前的状态。

一致性(Consistency)

一致性是指在事务执行过程中,数据库从一个一致性状态转换到另一个一致性状态。这意味着事务执行过程中不会破坏数据库的完整性约束,如主键、外键、约束等。

隔离性(Isolation)

隔离性是指在并发环境下,每个事务都应该被隔离开来,互不干扰。每个事务应该感觉到自己在单独地操作数据库,即使在并发执行的情况下也是如此。这意味着一个事务的结果不应该受到其他事务的影响。

持久性(Durability)

持久性是指在事务提交后,对数据库所做的更改应该永久保存在数据库中,并且即使在系统故障的情况下也应该得到保持。

在实际应用中,事务的隔离性是最容易被忽略的一个特性。当多个事务并发执行时,可能会出现一些问题,如脏读、不可重复读和幻读等问题。这些问题是由于事务之间的相互干扰导致的。

为了解决这些问题,数据库定义了四个事务隔离级别,分别为读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。不同的隔离级别提供了不同的事务隔离程度,具体如下:

读未提交(Read Uncommitted)

在此隔离级别下,一个事务可以读取另一个事务未提交的数据。这种隔离级别的优点是并发性高,但缺点是可能会出现脏读、不可重复读和幻读等问题。

读已提交(Read Committed)

在此隔离级别下,一个事务只能读取另一个事务已经提交的数据。这种隔离级别可以避免脏读的问题,但仍然可能出现不可重复读和幻读等问题。

可重复读(Repeatable Read)

在此隔离级别下,一个事务在执行期间读取的数据集合是固定的。这种隔离级别可以避免脏读和不可重复读的问题,但仍然可能出现幻读的问题。

串行化(Serializable)

在此隔离级别下,所有事务都是串行执行的。这种隔离级别可以避免所有并发问题,但是会降低并发性能。

需要注意的是,隔离级别越高,事务的并发性能就越低,因此需要根据具体的业务需求和性能要求进行适当的选择。

🚀并发事务问题

在数据库中,当多个事务同时并发执行时,可能会出现一些并发事务问题。这些问题包括脏读、不可重复读和幻读。下面我将对这些问题进行详细解读:

1. 脏读(Dirty Read)

脏读指的是一个事务读取了另一个事务未提交的数据。假设事务A修改了某个数据,但还没有提交,此时事务B读取了这个数据。如果事务A在后续的操作中回滚了,那么事务B读取的数据就是脏数据,即脏读。

2. 不可重复读(Non-Repeatable Read)

不可重复读指的是在一个事务内,由于并发事务的修改,同一查询条件的结果在事务执行过程中发生了变化。例如,事务A首先读取了某个数据,然后事务B修改了这个数据并提交,接着事务A再次读取相同的数据,发现数据已经发生了变化,这就是不可重复读。

3. 幻读(Phantom Read)

幻读指的是在一个事务内,由于并发事务的插入或删除操作,同一查询条件的结果集发生了变化。例如,事务A首先读取了某个范围的数据,然后事务B插入了符合这个范围的新数据并提交,接着事务A再次读取相同的范围数据,发现数据集合发生了变化,这就是幻读。

并发事务问题的解决方法

为了解决并发事务问题,数据库系统提供了不同的事务隔禅级别,如读未提交、读已提交、可重复读和串行化。通过设置不同的隔离级别,可以控制事务之间的相互影响,从而避免脏读、不可重复读和幻读等问题。

此外,还可以通过加锁机制来解决并发事务问题。数据库系统提供了行级锁、表级锁、页级锁等不同的锁机制,可以在事务执行过程中对数据进行加锁,从而避免并发事务问题的发生。

总的来说,合理设置事务隔离级别、使用合适的锁机制以及精心设计事务操作,可以有效地解决并发事务问题,确保数据库操作的一致性和完整性。

🚀事务隔离级别

隔离级别

脏读

不可重复读

幻读

Read uncommitted

Read committed

×

Repeatable Read(默认)

×

×

Serializable

×

×

×

查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

 设置事务隔离级别

SET TRANSACTION ISOLATION LEVEL <isolation_level>;

其中,<isolation_level>是指定的隔离级别,可以是以下四个隔离级别之一:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。

例如,要将事务隔离级别设置为可重复读(REPEATABLE READ),可以使用以下SQL语句:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
98 43
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1645 14
|
2月前
|
存储 Oracle 关系型数据库
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
从基本特性、技术选型、字段类型、事务提交方式、SQL语句、分页方法等方面对比Oracle和MySQL的区别。
543 18
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
|
1月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
2月前
|
SQL 关系型数据库 MySQL
MySQL基础:事务
本文详细介绍了数据库事务的概念及操作,包括事务的定义、开启、提交与回滚。事务作为一组不可分割的操作集合,确保了数据的一致性和完整性。文章还探讨了事务的四大特性(原子性、一致性、隔离性、持久性),并分析了并发事务可能引发的问题及其解决方案,如脏读、不可重复读和幻读。最后,详细讲解了不同事务隔离级别的特点和应用场景。
147 4
MySQL基础:事务
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL】索引和事务
【MySQL】索引和事务
55 0
|
2月前
|
SQL Oracle 关系型数据库
详解 MySQL 的事务以及隔离级别
详解 MySQL 的事务以及隔离级别
43 0
|
3月前
|
SQL 关系型数据库 MySQL
Mysql原理与调优-事务与MVCC
【8月更文挑战第19天】
|
3月前
|
存储 SQL 关系型数据库
深入解析MySQL事务机制和锁机制
深入解析MySQL事务机制和锁机制
|
3月前
|
算法 关系型数据库 MySQL
一天五道Java面试题----第七天(mysql索引结构,各自的优劣--------->事务的基本特性和隔离级别)
这篇文章是关于MySQL的面试题总结,包括索引结构的优劣、索引设计原则、MySQL锁的类型、执行计划的解读以及事务的基本特性和隔离级别。

热门文章

最新文章

下一篇
无影云桌面