Day06数据库基础之事务(事务的四大特性ACID和事务的隔离级别)

前言

1、事务操作有哪些?
2、事务的四大特征是什么?
3、事务的隔离级别(了解)

一、事务是什么?

1、定义: 在实际的开发过程中,一个业务操作如:转账,往往是要多次访问数据库才能完成的。转账是一个用户扣钱,另一个用户加钱。如果其中有一条 SQL 语句出现异常,这条 SQL 就可能执行失败。
(事务执行是一个整体,所有的 SQL 语句都必须执行成功。如果其中有 1 条 SQL 语句出现异常,则所有的SQL 语句都要回滚,整个业务执行失败。)

在这里插入图片描述

  • 模拟转账交易:张三给李四转 500 元钱
    1.首先创建一个数据表
-- 创建数据表
CREATE TABLE account (
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(10),
	balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('张三', 1000), ('李四', 1000);

2.一个转账的业务操作最少要执行下面的 2 条语句:
张三账号-500
李四账号+500

-- 张三账号-500
update account set balance = balance - 500 where name='张三';
-- 李四账号+500
update account set balance = balance + 500 where name='李四';

3.假设当张三账号上-500 元,服务器崩溃了。李四的账号并没有+500 元,张三账户上的500块钱不翼而飞了,这个时候就是数据出现问题了。

So ~我们需要保证,其中一条 SQL 语句出现问题,整个转账就是失败;只有两条 SQL 都成功了转账才算成功。这个时候就需要用到事务

二、事务操作

1、手动提交事务

1.执行成功的情况: 开启事务-> 执行多条 SQL 语句 -> 成功提交事务
2.执行失败的情况: 开启事务->执行多条 SQL 语句-> 事务的回滚
在这里插入图片描述
语法
开启事务:start transaction;
提交事务:commit;
回滚事务:rollback;

  • (1)还是刚刚模拟转账的例子1

    • 模拟张三给李四转 500 元(成功),张三和李四账户上都有1000块
      在这里插入图片描述

    • 执行以下 SQL 语句: 1.开启事务, 2.张三账号-500, 3.李四账号+500

    • 查看 SQLYog 数据库:发现数据并没有改变

    • 执行 commit 提交事务

    • 查看 SQLYog 数据库:发现数据改变
      在这里插入图片描述

  • (2)转账的例子2

    • 模拟张三给李四转 500 元钱(失败),张三和李四账户上都有1000块
      在这里插入图片描述
    • 在控制台执行以下 SQL 语句:1.开启事务, 2.张三账号-500
    • SQLYog 查看数据库:发现数据并没有改变
    • 执行 rollback 回滚事务
    • SQLYog 查看数据库:发现数据没有改变

总结: 如果事务中 SQL 语句没有问题,commit 提交事务,会对数据库数据的数据进行改变; 如果事务中 SQL语句有问题,rollback 回滚事务,会回退到开启事务时的状态,钱就不会不翼而飞啦。

2、自动提交事务

  • MySQL数据库中事务默认自动提交
  • 一条DML(增删改)语句会自动提交一次事务

3、修改事务的默认提交方式

  • 查看事务的默认提交方式:SELECT @@autocommit; 1 代表自动提交 0 代表手动提交*
  • 修改默认提交方式: set @@autocommit = 0;
    在这里插入图片描述

三、事务的四大特征

1、原子性

1.定义:每个事务都是一个整体,不可再拆分,事务中所有的 SQL 语句要么都执行成功,要么都失败

2、持久性

1.定义:事务提交或回滚成功后,对数据库的修改是持久的。就算关机,也是保存下来的

3、隔离性

1.定义:多个事务之间相互独立

4、一致性

1.定义:事务在执行前数据库的状态与执行后数据库的状态保持一致。如:转账前2 个人的总金额是 2000 ,转账后 2 个人总金额也是 2000

四、事务的隔离级别

并发操作,多个用户同时访问同一个数据,可能引发并发访问的问题:

1、脏读 :一个事务读取到了另一个事务中尚未提交的数据
2、不可重复读:一个事务中两次读取的数据 内容 不一致
3、幻读:一个事务中两次读取的数据的数量不一致

1、读未提交(read uncommitted)

会出现脏读、不可重复读、幻读的问题
1.打开 A 窗口登录 MySQL,设置全局的隔离级别为最低

mysql -uroot -proot
set global transaction isolation level read uncommitted;

在这里插入图片描述
2. 打开 B 窗口,AB 窗口都开启事务

use day23;
start transaction;

在这里插入图片描述
3. A 窗口更新 2 个人的账户数据,未提交

update account set balance=balance-500 where id=1;
update account set balance=balance+500 where id=2;

在这里插入图片描述
4. B 窗口查询账户

select * from account;

在这里插入图片描述
5. A 窗口回滚

rollback;

在这里插入图片描述
6. B 窗口查询账户,钱没有到账

在这里插入图片描述

2、读已提交(read committed)

1.在 A 窗口设置全局的隔离级别为 read committed

set global transaction isolation level read committed;

在这里插入图片描述
2.B 窗口退出 MySQL,B 窗口再进入 MySQL
在这里插入图片描述
3.AB 窗口同时开启事务
在这里插入图片描述
4.A 更新 2 个人的账户,未提交

update account set balance=balance-500 where id=1;
update account set balance=balance+500 where id=2;

在这里插入图片描述
5.B 窗口查询账户
在这里插入图片描述
6.A 窗口 commit 提交事务
在这里插入图片描述
7.B 窗口查看账户
在这里插入图片描述
这个时候会发现一个问题: 解决脏读的问题,出现不可重复读、幻读的问题在这里插入图片描述

3、可重复读(repeatable read)

解决脏读、不可重复的问题,出现幻读的问题,这是数据库MySQL默认的级别

  1. A 窗口设置隔离级别为: repeatable read
set global transaction isolation level repeatable read;

在这里插入图片描述
2. B 窗口退出 MySQL,B 窗口再进入 MySQL
在这里插入图片描述
3.AB同时开启事务

start transaction;

在这里插入图片描述
4.A 窗口更新数据并提交

update account set balance=balance+500 where id=1;
commit;

在这里插入图片描述
5.B窗口查询

select * from account;

在这里插入图片描述

4、串行化(serializable )在 MySQL 中无法看到幻读的效果
解决以上脏读、不可重复读、幻读的问题
1.开启 A 窗口

set global transaction isolation level serializable;

在这里插入图片描述
2. A 窗口退出 MySQL,A 窗口重新登录 MySQL

start transaction;
select count(*) from account;

在这里插入图片描述
3. 再开启 B 窗口,登录 MySQL
4. 在 B 窗口中开启事务,添加一条记录

start transaction; -- 开启事务
insert into account (name,balance) values ('LaoWang', 500);

在这里插入图片描述
5.在 A 窗口中 commit 提交事务,B 窗口中 insert 语句会在 A 窗口事务提交后立马运行
在这里插入图片描述
6.在 A 窗口中接着查询,发现数据不变

select count(*) from account;

在这里插入图片描述
7. B 窗口中 commit 提交当前事务
在这里插入图片描述
8. A 窗口就能看到最新的数据
在这里插入图片描述

总结
1、1234级别依次增加,1的隔离级别最低,4的隔离级别最高,隔离级别越高,安全性越高,但是效率越低
2、 数据库查询隔离级别:select @*@tx_isolation;
3、数据库设置隔离级别:set global transaction isolation level 级别字符串;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值