MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别)

MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别)

文章目录

1. 事务简介2. 事务操作2.1 未控制事务2.2 控制事务2.2.1 查看事务的提交方式2.2.2 设置事务的提交方式2.2.3 提交事务2.2.4 回滚事务2.2.5 开启事务2.2.6 完善转账案例

3. 事务的四大特性(ACID)4. 并发事务引发的问题5. 事务隔离级别5.1 演示5.1.1 Read Uncommitted(RU)5.1.2 Read Committed(RC)5.1.3 Repeatable Read(RR)5.1.4 Serializable

5.2 查看隔离级别5.3 设置事务隔离级别

1. 事务简介

DBMS:Database Management System,数据库管理系统

事务(Transaction)是数据库管理系统(DBMS)中一个不可分割的工作单位,它由一系列操作组成,这些操作要么全部成功执行,要么全部失败回滚,不会处于中间状态

事务的主要目的是保证数据的一致性和完整性,常见的事务案例就是银行转账

我们先来看一下正常的银行转账业务

我们再来看一下转账异常的情况,如果张三取出钱后,再转账给李四的过程中业务出现了异常,会怎么样呢

如果业务出现了异常,张三的钱扣了,但是李四却没收到钱,出现了数据不一致的情况

那怎么解决呢,我们只需要把整个流程都放在一个事务里面,当所有操作都执行完成了之后,再提交事务

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

2. 事务操作

我们先准备一张名为 account 的表,表的结构和表数据如下

create table account

(

id int primary key AUTO_INCREMENT comment 'ID',

name varchar(10) comment '姓名',

money double(10, 2) comment '余额'

) comment '账户表';

insert into account(name, money)

VALUES ('张三', 2000),

('李四', 2000);

2.1 未控制事务

我们先来测试正常情况

-- 1.查询张三余额

select *

from account

where name = '张三';

-- 2.张三的余额减少1000

update account

set money = money - 1000

where name = '张三';

-- 3.李四的余额增加1000

update account

set money = money + 1000

where name = '李四';

测试完毕之后检查数据的状态, 可以看到数据操作前后是一致的

测试异常情况

我们先把数据都恢复到2000, 接着一次性执行以下 SQL 语句

-- 1.查询张三余额

select *

from account

where name = '张三';

-- 2.张三的余额减少1000

update account

set money = money - 1000

where name = '张三';

出错了....

-- 3.李四的余额增加1000

update account

set money = money + 1000

where name = '李四';

由于 出错了.... 这句话 不符合 SQL 语法,执行后会报错

检查最终的数据情况,发现数据在操作前后并不一致

2.2 控制事务

2.2.1 查看事务的提交方式

SELECT @@autocommit;

2.2.2 设置事务的提交方式

autocommit = 1 表示自动提交

SET @@autocommit = 0;

2.2.3 提交事务

commit;

2.2.4 回滚事务

rollback;

2.2.5 开启事务

start transaction;

2.2.6 完善转账案例

-- 开启事务

start transaction;

-- 1.查询张三余额

select *

from account

where name = '张三';

-- 2.张三的余额减少1000

update account

set money = money - 1000

where name = '张三';

-- 3.李四的余额增加1000

update account

set money = money + 1000

where name = '李四';

-- 如果正常执行完毕, 则提交事务

commit;

-- 如果执行过程中报错, 则回滚事务

rollback;

3. 事务的四大特性(ACID)

原子性(Atomicity): 原子性确保事务中的所有操作要么全部完成,要么全部不完成,不会出现部分完成的情况。事务中任何一个操作失败,整个事务将被回滚,就像事务从未执行过一样一致性(Consistency): 一致性确保事务执行的结果是数据库状态的合法状态,即数据库在事务开始和结束时的数据满足预定义的约束条件(如外键约束、唯一性约束等)隔离性(Isolation): 隔离性确保并发执行的事务彼此隔离,一个事务的中间状态不会被其他事务所见。这意味着即使在多个事务同时执行时,每个事务都感觉自己是唯一在执行的事务持久性(Durability): 持久性确保一旦事务提交,其结果就永久保存在数据库中。即使发生系统故障,如电源故障或系统崩溃,已提交事务的结果也不会丢失,持久性一般是通过将事务的输出写入到持久存储设备(如硬盘)来保证

4. 并发事务引发的问题

赃读:一个事务读到另外一个事务还没有提交的数据不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影"

脏读的示例(事务 A 中没提交的数据被事务 B 读取)

不可重复读的示例(事务 A 在第一步和第三步查询的 id 为 1 的数据不一致)

幻读的示例

事务 A 在第一步查询到 id 为 1 的数据不存在事务 A 在执行 insert 语句前,事务 B 提交了事务,往表中插入了 id 为 1 的数据事务 A 在第二步执行 insert 语句,执行失败,因为破坏了主键的唯一性事务 A 在第三步查询到 id 为 1 的数据仍然不存在

5. 事务隔离级别

为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别,事务隔离级别主要有以下几种:

5.1 演示

我们来演示一下,在不同的隔离级别情况下,并发事务可能引发的问题

5.1.1 Read Uncommitted(RU)

脏读(一个事务读到了另一个事务还没有提交的数据)

5.1.2 Read Committed(RC)

Read Committed 隔离级别虽然解决了脏读问题,但是没有解决不可重复读的问题(一个事务先后读取同一条记录,但两次读取的数据不同)

5.1.3 Repeatable Read(RR)

Read Committed 隔离级别虽然解决了不可重复读问题,但是没有解决幻读的问题(一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影")

5.1.4 Serializable

Read Committed 隔离级别解决了所有并发事务引发的问题

5.2 查看隔离级别

查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

5.3 设置事务隔离级别

SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

SESSION 设置的是当前会话(也就是当前连接)的隔离级别GLOBAL 设置的是全局隔离级别

事务隔离级别越高,数据越安全,但是性能越低

示例

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

你可能也喜欢

绿豆的十大功效与作用
Bte365

绿豆的十大功效与作用

06-27 6592
泰拉瑞亚全部NPC复活方法与入住条件攻略
下载365APP手机客户端

泰拉瑞亚全部NPC复活方法与入住条件攻略

08-07 1213
微信支付后如何申请退款
下载365APP手机客户端

微信支付后如何申请退款

08-02 8948