Mysql16——事务简述

mysql 事务

一 什么是事务

[Transaction]

事务(Transaction)是一组数据库操作,这些操作被视为一个逻辑单元,要么全部成功执行,要么全部失败回滚。事务主要用于确保数据库操作的一致性和可靠性。

事务本质就是一组SQL语句,理论上,事务本就不应该属于MySQL,而是应该在应用层上面,完成的一件事情,完成一系列相关操作的sql语句集合叫做事务

假如说你从学校毕业了,那么学校 教务系统,后台的MySQL中就不需要你的信息了,那么管理员会运行几条sql命令来输出你的(姓名,电话,籍贯等信息),同时还有一些sql操作输出你的成绩,这些操作组合起来,就构成了一个"事务"

事务=原子性的操作多条的sql语句

在这里插入图片描述

再比如:

张三给李四转账1000
张三的账户余额update减少1000,李四的账户余额update增加1000,在数据库角度是执行两条sql
所有的sql操作,一般都会被mysql包装成事务,无论是一条还是多条的sql,都是一样的对待的

一个完整的事务,绝不是简单的sql集合,还必须要满足4条属性ACID

  • 原子性(atomicity,或称不可分割性),

原子性确保事务中的所有操作要么全部成功,要么全部失败回滚(rollback)。如果事务中的任何操作失败,将撤消已经完成的操作,恢复到事务开始前的状态。

  • 一致性:(Consistency):

一致性确保事务使数据库从一个一致状态转换到另一个一致状态。也就是说,在事务开始和结束时,数据必须符合预定义的一致性规则。如果事务在执行过程中违反了一致性规则,系统将回滚到事务开始时的状态。

比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱

  • 隔离性:(isolation,又称独立性):

隔离性确保并发执行的事务彼此隔离,互不干扰。每个事务都认为它是唯一在执行的事务,并具有对数据的独占访问权限,未提交的数据对其他事务是不可见的。隔离级别的设置可以控制事务之间的隔离程度。

  • 持久性:(durablity):

持久性确保一旦事务提交,对数据库的更改将永久保存,即使在系统故障或重启后也能恢复。持久性通过将数据写入非易失性存储介质(如硬盘)来实现,从而保证事务的持久性。

事务就是由单独单元的一个或多个sql语句组成,在这个单元中,每个sql语句都是相互依赖的。而整个单独单元是作为一个不可分割的整体存在,类似于物理当中的原子(一种不可分割的最小单位)。

往通俗的讲就是,事务就是一个整体,里面的内容要么都执行成功,要么都不成功。不可能存在部分执行成功而部分执行不成功的情况。

就是说如果单元中某条sql语句一旦执行失败或者产生错误,那么整个单元将会回滚(返回最初状态)。所有受到影响的数据将返回到事务开始之前的状态,但是如果单元中的所有sql语句都执行成功的话,那么该事务也就被顺利执行。

在mysql中,innodb引擎支持事务(transaction),而myisam,memory等不支持事务。

二、事务的分类

事务分类有多种分类模式,下面介绍几种分类。

分类方式一:

事务分为隐式事务显式事务两种。我们的DML语句(insert、update、delete)就是隐式事务。

  • 隐式事务:该事务没有明显的开启和结束标记,它们都具有自动提交事务的功能;不妨思考一下,update语句修改数据时,是不是对表中数据进行改变了,它的本质其实就相当于一个事务。
  • 隐式事务是MySQL自动执行的事务,也称为自动提交事务。默认情况下,每个SQL语句都会自动成为一个隐式事务,并在执行完毕后自动提交。这意味着每个SQL语句都作为一个事务单元进行处理,但无法回滚或手动提交。

举一个栗子:张三同学买了一个机械键盘花了158元,是不是就是update语句对字段name为张三的同学的余额balance进行减158元的处理呢?示例代码如下:

update account set balance = balance - 158 where name = "张三"
  • 显示事务:该事务具有明显的开启和结束标记;也是本文重点要讲的东西。使用显式事务的前提是你得先把 自动提交事务的功能给禁用。禁用自动提交功能就是设置autocommit变量值为0**(0:禁用 1:开启)**
  • 显式事务是通过使用BEGIN、COMMIT和ROLLBACK语句来手动启动和控制的事务。BEGIN语句用于开始一个事务,COMMIT语句用于提交事务,ROLLBACK语句用于回滚事务。显式事务给予开发者更多的控制权,并允许将多个SQL语句组合成一个原子操作。
  • 示例:
BEGIN; 
-- 执行一系列SQL语句
COMMIT; -- 提交事务

先查看一下当前的autocommit变量值,发现当前处于开启自动提交事务的状态

select @@autocommit;
# (0:禁用 1:开启)

禁用自动提交事务的功能并查看当前状态

set autocommit = 0;  # 禁用自动提交事务的功能
select @@autocommit;  # 查看自动提交事务是否禁用,为0即表示禁用

三、开启事务的步骤

account表已经存在

SELECT * FROM account;

在这里插入图片描述

#步骤一:开启事务(可选)
start transaction;
# 步骤二:编写事务中的sql语句(insert、update、delete)
# 这里实现一下"张三给李四转账"的事务过程
update account set balance = 1400 where name = "张三";
update account set balance = 1600 where name = "李四";
#步骤三:结束事务
commit; #提交事务
# rollback; #回滚事务:就是事务不执行,回滚到事务执行前的状态

在这里插入图片描述

运行结果:

SELECT * FROM account;

在这里插入图片描述

四、事务并发时出现的问题

但是呢,因为某一刻不可能总只有一个事务在运行,可能出现A在操作account表中的数据,B也同样在操作account表,那么就会出现并发问题,对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采用必要的隔离机制,就会发生以下各种并发问题。

当事务并发执行时,可能会出现以下几个问题:

  1. 脏读(Dirty Read):脏读是指一个事务读取了另一个并发事务尚未提交的数据。如果这个未提交的事务最终被回滚,那么读取到的数据就是无效的或不一致的。

    对于两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效

  2. 不可重复读(Non-Repeatable Read):不可重复读是指一个事务在同一个事务中多次读取同一数据时,得到的结果不一致。这是因为在这个期间,另一个并发事务修改了被读取的数据并提交了更改。

    对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段之后,T1在读取同一个字段,值就不同了

  3. 幻读(Phantom Read):幻读是指一个事务在同一事务中多次进行查询,但每次查询返回的记录数不一致。这是因为在这个期间,另一个并发事务插入或删除了符合查询条件的数据。

    对于两个事务T1,T2,T1在A表中读取了一个字段,然后T2又在A表中插入了一些新的数据时,T1再读取该表时,就会发现神不知鬼不觉的多出几行了…

  4. 更新丢失(Lost Update):更新丢失是指两个或多个事务同时读取同一数据,并试图将其修改后写回数据库。由于并发操作的顺序和时间差异,可能只有最后一个事务的修改生效,从而丢失了其他事务的更新。

  5. 死锁(Deadlock):死锁是指两个或多个事务相互等待对方持有的资源,导致所有事务无法继续执行。这种情况下,系统需要通过回滚一个或多个事务来解除死锁。

为了解决并发执行时可能出现的问题,数据库管理系统提供了各种并发控制机制和隔离级别。事务隔离级别(如读未提交、读已提交、可重复读和串行化)可以设置事务之间的隔离程度,从而解决并发问题。此外,锁定机制、多版本并发控制(MVCC)、时间戳等技术也被用于确保数据的一致性和并发的正确执行。

通过回滚一个或多个事务来解除死锁。

为了解决并发执行时可能出现的问题,数据库管理系统提供了各种并发控制机制和隔离级别。事务隔离级别(如读未提交、读已提交、可重复读和串行化)可以设置事务之间的隔离程度,从而解决并发问题。此外,锁定机制、多版本并发控制(MVCC)、时间戳等技术也被用于确保数据的一致性和并发的正确执行。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值