MySQL中的事务

MySQL中的事务(MySQL8版本)

定义

数据库事务(Transaction)是访问并可能操作各种数据项的一个数据库操作的序列是一个不可分割的工作单位
事务是由事务开始与事务结束之间执行的全部数据库操作。

在MySQL当中是只有InnoDB引擎的数据库或表是支持事物的。事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部都不执行。

使用用来的管理语句都包含有INSERT、UPDATE、DELETE语句。

特性

一般来说,事务是必须满足4个条件的(ACID): 原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,或称独立性)、持久性(Durability)。

1. 原子性(Atomicity)

一个事务(Transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间的某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的某个状态,就像这个事务从来没有执行过一样。

举例:张三向李四转账100块,但突然断电,张三已经转出去了100快,但李四并没有收到钱,这样就产生了较大的问题。所以就要解决此类的问题。
解决这个问题就是数据库的原子性,规定要么这两件事都执行了,要么这两件事都没有执行。

2. 持久性(Durability)

持久性即就是当一个事务提交后,对数据的改变是永久性的,是不会被回滚的。

就是除过正常的增删改等操作以外,即使系统故障这些意外都不会让数据库的数据改变或丢失。

3. 隔离性(Isolation)

数据库是允许多个并发事务同时对其进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉而导致数据的不一致。事务隔离分为不同级别的,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

4. 一致性(Consistency)

就是在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据时必须符合所有的预测规则。

例子:比如上面转钱的列子,就必须保证传出传入的金额必须一致。

一致性就是前三种特性的集合

隔离性中对并发事务处理时的问题

当两个或者多个事务选择表中同一行进行操作的时候,然后基于最初的选定的值进行更新操作时,由于每个事务都不知道其他事务的存在,所以就会发生丢失更新的问题,即最后的更新并覆盖了前一个程序所做的更改。

事务之间相互影响的种类:
脏读 不可重复读 幻读 丢失更新

假设有两个事务A和B,同时并发:

脏读

一个事务读取了另一个事务未提交的数据

比如,数据表中id为1行的age本身为18;

①事务A修改了id为1的age数据为20

②然后事务B立刻读取了id为1的行数据

③但是事务A在这时发生了事务回滚,返回了id为1行的age数据为18。

显然这样的情况是很不合理的。
在这里插入图片描述

不可重复读

在事务A中先后两次读取同一数据,但两次读取的结果是不一样的,这种现象称为不可重复读。

脏读与不可重复读的区别:前者读到的是其他事务未提交的数据,后者读到的其他事务已提交的数据。

在一个事务当中,两次读取的结果不一样这显然也是不可以的。是我们所不能接受的现象。
在这里插入图片描述

这就叫做幻读:在同一个事务中两次读取到的数据量不一致。一般幻读出现在范围查询。

幻读

就是指当事务不是独立执行时发生的一种现象

例如:在事务A中按照某个条件进行先后两次的查询,但是两次查询结果的条数是不同的,这种现象称为幻读。

不可重复读与幻读的区别:前者是查的数据中的某个数据变了,后者是前后查询出来的行数变了。
在这里插入图片描述

事务的设置

默认情况下,MySQL启用的是自动提交模式(变量 autocommit 为 ON)。这就意味着,只要你执行了DML(数据库操作语言)操作语句,MySQL会立即隐式的提交事务。

由于变量autocommit分会话系统变量与全局系统变量,所以查询的时候,最好区别是会话系统变量还是全局系统变量。

1. 在SQL中查询autocommit模式:

SHOW SESSION(会话) / GLOBAL(全局) VARIABLES LIKE 'autocommit';

SHOW GLOBAL VARIABLES LIKE 'autocommit';

在这里插入图片描述

默认它是开启的。

2. 改变MySQL的自动提交模式

SET SESSION / GLOBAL autocommit=0; 禁止自动提交
SET SESSION / GLOBAL autocommit=1; 开启自动提交

SET GLOBAL autocommit=0;
SHOW GLOBAL VARIABLES LIKE 'autocommit';

在这里插入图片描述

关闭了SQL当中全局的事务默认提交。

3. 实现事务
使用BEGIN, ROLLBACK, COMMIT 来实现

BEGIN; / START TRANSACTION; 开始一个事务
SQL操作语言;
ROLLBACK; #事务回滚
COMMIT; #事务确认

BEGIN; #开启事务

INSERT INTO student(NAME) VALUES ('Jim'); #向表中存入一个数据

在这里插入图片描述

ROLLBACK;  
#对事务进行回滚,就是撤回操作语言,因为开启事务还没有确认事务,
#意为这件事还没有结束可以对其进行操作

在这里插入图片描述

COMMIT; #事务确认

确认事务后,就不能在对事务里的操作语言进行回滚了。

再举一列:

BEGIN;		#开启事务
INSERT INTO student(NAME) VALUES ('Tom');
COMMIT;		#确认事务
ROLLBACK;	#回滚

在这里插入图片描述

很明显对这条语句是没有进行回滚的,因为ROLLBACK是在COMMIT语句之后的。确认事务后就要遵从事务的特性了。

事务的隔离级别

在MySQL当中,只有InnoDB是支持事务的,所以在这里所所说的事务隔离级别是指InnoDB下的事务隔离级别。

查看当前的隔离级别

SELECT @@global.transaction_isolation,@@transaction_isolation;

在这里插入图片描述

设置隔离级别。

SET SESSION/GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别;

  1. 读未提交(read uncommitted)(几乎不用)
    一个事务可以读取到另一个事务未提交的修改。
    这会带来脏读、幻读,不可重复读问题。
  2. 读已提交(read committed)
    一个事务只能读取另一个事务已经提交的修改。 其避免了脏读。
    但仍然存在不可重复读和幻读问题。
  3. 可重复读(repeatable read)(MySQL中的默认隔离级别)
    同一个事务中多次读取相同的数据返回的结果是一样的,避免了脏读和不可重复读问题。(在MySQL8的InnoDB之前存在幻读情况,在8之后也没有了幻读情况)
  4. 串行化(serializable)(性能最低)
    事务串行执行,避免了以上所有问题。一次只能允许一个事务进行操作。
    是最安全的,但效率是最低的。
事务隔离级别脏读不可重复读幻读
未提交读(Read Uncommitted)可能可能可能
已提交读(Read Committed)不可能可能可能
可重复读(Repeatable Read)不可能不可能InnoDB引擎不可能
串行化(Serializable)不可能不可能不可能

下一章: ====》 SQL中的MVCC详解(快照)

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL事务隔离是数据库事务处理的一个关键概念,它用于控制并发访问数据库时的一致性。事务隔离级别定义了不同用户在同一时间对数据的操作如何互相影响。MySQL提供了几种不同的事务隔离级别: 1. **读未提交(READ UNCOMMITTED)**:这是最低的隔离级别,事务可以读取其他事务未提交的数据,可能导致脏读(读取到的是未提交更新的数据)和幻读(查询结果因其他事务的插入或删除而改变)。 2. **读已提交(READ COMMITTED)**:在此级别,事务只能看到已经提交的变更。这防止了脏读,但仍然可能面临不可重复读(由于其他事务的更新,相同的查询返回不同的结果)。 3. **可重复读(REPEATABLE READ)**:在此模式下,事务在其整个生命周期内不会看到其他事务对其已锁定行的更改,这保证了事务的隔离性和一致性,但是可能出现幻读(如果另一个事务在该事务范围内插入了新行)。 4. **串行化(SERIALIZABLE)**:这是最高的隔离级别,保证了每个事务好像在单独使用数据库一样执行,完全避免了并发冲突,但性能开销最大。 选择哪个隔离级别取决于应用的具体需求。例如,如果对数据一致性要求很高,会选择可重复读或串行化,但如果希望提高并发性能,可能会接受较低级别的隔离,但可能需要更复杂的并发控制策略。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值