mysql学习录(四)事务处理

是在 MySQL 绿色版 8.0.25下测试学习的

事务

为什么使用事务

理解:

为了解决一些并发的业务或者解决需要一组sql语句组合才能成为一个完整的逻辑工作处理单元的操作(实现功能)。比如最经典的转账业务,一个人卡上账户余额减少一定的金额,同时被转账的那个人的余额增加相应的金额。

什么是事务

1.概念:

构成单一逻辑工作单元的操作集合称作事务(transaction),它是作为不可分割的逻辑单元执行的一组sql语句。

2.具体理解事务:
场景:

转账:杨过给小龙女转账5000,杨过的账户减少5000,小龙女的账户上增加5000。

代码
##	设存在 t_accounts 表,其中存在两个账户 【卡号,户主,余额】

   id   card_no     name   balance
   1    123666321   杨某   20000
   2    456888654   龙某   10000
##	
	#0、开启事务
      begin ;
      
    #1、杨某 账户上减少 5000
      UPDATE t_accounts SET balance = balance - 5000 WHERE card_no = '123666321' ;

    #2、龙某 账户上增加 5000
      UPDATE t_accounts SET balance = balance + 5000 WHERE card_no = '456888654' ;

    #3、提交事务
      commit ;
3.连接、会话的理解:

连接(connection):客户端程序(Java、C、js、命令提示符界面连接MySQL服务、Navicat客户端等等)与MySQL服务之间构建联接。成功之后,就可以算一次会话,就可以操作MySQL服务了。

会话(session):一次连接成功就可以算一个会话,一个会话可以发生许多事务(Transtaction)。

事务的特性

Atomicity(原子性)

事务中所有特性要么都发生,要么都不发生。(事务操作做了一半由于一些因素后面的操作发生不了,则撤销之前成功的操作,恢复到没有发生事务操作的状态)

Consistency(一致性)

事务将数据库从一种一致状态转变为下一组一致状态

Isolation(隔离性)

事务和事务之间是彼此独立隔离的。

Durability(持久性)

事务一旦提交,其结果就是持久的。

事务代码流程

下面步骤是在MySQL命令行下进行的操作:

## 连接MySQL服务  -->  一个会话  -->已经开启了一个自动提交的事务(隐式开启)
# 1.在当前会话中自主控制事务的提交与回滚,需要关闭系统自动提交事务的变量值。
 SET @@autocommit = 0;  # 系统变量@@autocommit 默认 是 1 ,系统自动提交事务  改为0  人为手动提交事务
# 2.一组sql语句操作
DML语句【INSERT, UPDATE, DELETE】等
# 3.回滚(撤销事务中的所有操作)
rollback;

# 4.提交事务(意味着终结该事务)
commit;
## 在同一个会话中 一旦提交一个事务  则会开启一个新的事务

事务控制语句

1) 事务 SQL 控制语句

START TRANSACTION (或 BEGIN ):显式开始一个新事务

SAVEPOINT :分配事务过程中的一个位置,以供将来引用

COMMIT :永久记录当前事务所做的更改

ROLLBACK :取消当前事务所做的更改

ROLLBACK TO SAVEPOINT :取消在 savepoint 之后执行的更改

RELEASE SAVEPOINT :删除 savepoint 标识符

SET AUTOCOMMIT :为当前连接禁用或启用默认 autocommit 模式

2)autocommit 模式:

如何设置 AUTOCOMMIT 模式决定了如何以及何时开始新事务。默认情况下, AUTOCOMMIT 处于全局启用状态,这意味着会强制每个 SQL 语句隐式开始一个新事务。可以通过一个选项文件全局禁用 AUTOCOMMIT ,也可以通过设置 autocommit 变量为每个会话禁用它 set @@autocommit = 0;

启用 AUTOCOMMIT 会限制每个语句,并进而影响其自身事务中的事务表。这样可以有效地防止在一个事务中执行多个语句。这意味着,您将无法通过 COMMIT 或 ROLLBACK 作为一个单元提交或回滚多个语句。有时,会将这种情况误认为根本没有事务。但是,情况并非如此。启用 AUTOCOMMIT 后,每个语句仍会以原子方式执行。例如,通过在插入多个行时比较违反约束限制的效果,便可看出启用 AUTOCOMMIT 和根本不具有事务之间的差别。在非事务表(如 MyISAM )中,一旦发生错误,语句就会终止,已经插入的行会保留在该表中。而对于 InnoDB 表,已经插入的所有行都会从该表中删除,从而不会产生任何实际影响。

AUTOCOMMIT 确定开始新事务的方式和时间;默认情况下, AUTOCOMMIT 模式处于启用状态:作为一个事务隐式提交每个语句;

使用 SELECT 检查 AUTOCOMMIT 设置:为1是自动提交模式,0是手动提交模式。

SELECT @@AUTOCOMMIT;
3) 隐式提交:

COMMIT 语句始终会 显式提交 当前事务。其他事务控制语句 还具有隐式提交当前事务的作用。DDL语句等

除了这些事务控制语句之外,其他类型的语句可能也具有隐式提交并进而终止)当前事务的作用。这些语句的行为就像在执行实际语句之前发出 COMMIT 一样。此外,这些语句本身并非事务语句,也就是说,如果成功,则无法回滚。通常,数据定义语句、据访问和用户管理语句以及锁定语句具有这种效果。

隐式提交 会终止当前事务。用于隐式提交的 SQL 语句:

START TRANSACTION

SET AUTOCOMMIT = 1

导致提交的非事务语句:

数据定义语句( ALTERCREATEDROP )

管理语句( GRANTREVOKESET PASSWORD )

锁定语句( LOCK TABLESUNLOCK TABLES

导致隐式提交的语句示例:

Mysql>TRUNCATE TABLE

Mysql>LOAD DATA INFILE

多事务并发

多事务并发可能发生的问题与相应的简单解决方案
1.Lost Update 更新丢失:

a. 第一类更新丢失,回滚覆盖:撤消一个事务时,在该事务内的写操作要回滚,把其它已提交的事务写入的数据覆盖了。
在这里插入图片描述

b. 第二类更新丢失,提交覆盖:提交一个事务时,写操作依赖于事务内读到的数据,读发生在其他事务提交前,写发生在其他事务提交后,把其他已提交的事务写入的数据覆盖了。这是不可重复读的特例。
在这里插入图片描述

解决第一类更新丢失:read uncommitted 即可

2.Dirty Read 脏读:

一个事务读到了另一个未提交的事务写的数据。
在这里插入图片描述

解决脏读:read committed 即可

3.Non-Repeatable Read 不可重复读:

一个事务中两次读同一行数据,可是这两次读到的数据不一样。
在这里插入图片描述

解决不可重复读:repeatable read 即可

4.Phantom Read 幻读:

一个事务中两次查询,但第二次查询比第一次查询多了或少了几行或几列数据。
在这里插入图片描述

解决幻读:serialization 可串行化

在这里插入图片描述
在这里插入图片描述

事务隔离级别

为了解决多个事务并发会引发的问题,进行并发控制。数据库系统提供 了四种事务隔离级别供用户选择。

Read Uncommitted 读未提交:

不允许第一类更新丢失。允许脏读,不隔离事务。

Read Committed 读已提交:

不允许脏读,允许不可重复读。

Repeatable Read 可重复读:

不允许不可重复读。但可能出现幻读。

Serializable 串行化:

所有的增删改查串行执行。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值