事务和隔离级别我也是懵逼!!

什么是事务?

事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取。

本质:由一个或多个sql语句组成。

事务的ACID原则?

  1. 原子性:事务执行一致,要么都成功要么都失败!如果有一个事务失败,那么就会发生回滚,所有事务保持原来状态。

  2. 一致性:事务执行完成数据保持一致!(A给B打了100块钱,A就少了100,B就多了100)

  3. 隔离性:同一条数据同一个时刻,只能有一个事务在操作!不能被其他事务所干扰!

  4. 持久性:执行了事务,结果一直报存下来。

并发事务下的问题?

  • 脏读:事务a读取了事务b还没有提交的事务
  • 不可重复读:事务a先后读取来了两次某个数据,两次数据不一致
  • 幻读:一个事务执行两次查询,但是第二次查询中包含了第一次查询时未出现的数据。(和插入删除有关)

事务的隔离级别(在数据库操作中,为了有效保证并发读取数据的正确性)

事务隔离级别越高,在并发下会产生的问题就越少,但同时付出的性能消耗也将越大,因此很多时候必须在并发性和性能之间做一个权衡

  1. read uncommited(读未提交:脏读) 不能解决 脏读,不可重复读,和幻读的问题
a-->开启事务-->查询余额为1000
b-->开启事务-->取走100元-->事务没提交
a-->查询余额为900
总结:b事务没提交 a都能查询到 b更新的数据()
----建立一新个连接 执行以下语句-------------
SELECT @@tx_isolation; #查看当前事务级别 为默认级别 REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;#修改事务级别 为 READ UNCOMMITTED
USE test;#使用test数据库
START TRANSACTION;#开启事务a
SELECT * FROM account;#第一次查询 余额1000
SELECT * FROM account;# b事务修改后第二次查询 余额为900
SELECT * FROM account;#第三次查询 b事务 回滚后查询 余额为 1000
---------------重新建立一个新连接执行以下语句--------------
SELECT @@tx_isolation;#查看当前事务级别  为默认级别 REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;#修改事务级别 为 READ UNCOMMITTED
USE test;#使用test数据库
START TRANSACTION;#开启b事务
UPDATE account SET balance=1000-100 WHERE id=1; #b事务 取100元--->未提交
SELECT * FROM account; #查看余额 为900
ROLLBACK;#回滚
SELECT * FROM account;#查看余额为1000
  1. read commited(读提交:不可重复读) 解决了脏读,不能解决 不可重复读的问题
a-->开启查询事务-->显示余额1000元
b-->开启取钱事务-->取走100元-->事务没提交
a-->查询 余额为 1000
b-->提交事务
a-->查询余额变成900元
总结:b事务没提交,b更新的数据a查询不到,b提交后 a才能查询到;(读到的两次数据不一致)
-----------a事务命令行--------
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;#修改事务级别 为 READ COMMITTED
USE test;#使用test数据库
START TRANSACTION;#开启事务a
SELECT * FROM account;#第一次查询 余额900
SELECT * FROM account;#第二次查询 b事务修改后查询 余额还是为900
SELECT * FROM account;#第三次查询 b事务 提交后查询 余额为 800
-------------------b事务命令行-----------------------------
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
USE test;
START TRANSACTION;#开启b事务
UPDATE account SET balance=balance-100 WHERE id=1; #b取100元
SELECT * FROM account; #查看余额 为800
COMMIT;
SELECT * FROM account;#查看余额为800

  1. repeatable read(重复读) 解决了 ,脏读 ,不可重复读的问题,可能没有解决幻读的问题(视情况而定)
a-->开启查询事务-->显示余额1000元
b-->开启取钱事务-->取走100元-->事务没提交
a-->查询 余额为 1000
b-->提交事务
a-->查询余额还是1000元-->提交事务
a-->查询 余额为 900元
总结:b事务更新,提交,a查询不到,只有 a提交后 a才能查询到 b更新的数据;相当于在a拿了一把锁,没还锁之前没人可以进来修改a那个时候的数据;
--------------a事务 REPEATABLE READ------------------
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;#修改事务级别为REPEATABLE READ
USE test;#使用test数据库
START TRANSACTION;#开启事务a
SELECT * FROM account;#余额800
SELECT * FROM account;# b事务修改后查询 余额还是为800
SELECT * FROM account;# b事务 提交后查询 余额还是为 800
COMMIT ;
SELECT * FROM account;#a自己的事务提交后 查询 余额 为700


-------------b事务 REPEATABLE READ----------------------------------
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;#修改事务级别为REPEATABLE READ
USE test;#使用test数据库
START TRANSACTION;#开启b事务
UPDATE account SET balance=balance-100 WHERE id=1; #b取100元
SELECT * FROM account; #查看余额 为700
COMMIT;
SELECT * FROM account;#查看余额为700

  1. serializable(序列化)可以解决 脏读 不可重复度 幻读的问题
a-->开启事务
b-->开启事务 -->执行操作-->报错
总结:a事务没提交之前 b事务不能执行 相关操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值