事务的概念及四种隔离级别

什么是事务

  • 概念
    逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败
  • 举例
    举例而言,支付宝转账,这一个操作可以分解成两个单元,转账人扣掉转账的金额,收款人收到转账的金额,那么什么情况下才可以算转账成功呢?自然是转账人被扣款了,收款人也要收到款项了,这样这个操作才算成功了,因此转账这个操作就是一个事务,只有两个单元同时成功了才算成功,若两者中的任何一个单元失败,则两个单元都应该失败,而不会也不应该出现一个单元成功另外一个单元失败的情况。

事务的特性:

  • 原子性
    事务不可分割
    以转账的例子而言,转账这个事务的原子性也即是说:转账的转出部分和转入部分不可以分开
  • 一致性
    事务执行数据前后一致
    以转账的例子来说,转账这个事务的一致性也就是说:转账前转出前账户A的金额 + 转入前账户B的金额 = 转出后账户A的金额 + 转入后账户B的金额,也就是说总体的金额是不会改变的。也就是不会出现我们之前说的两个单元中一个成功一个失败的情况,假设会出现一个成功一个失败的情况:转出成功了,账户少了100,但是转入失败了,转账操作成功了,那么总的金额是不是就少了100,这样就不满足事务执行前后数据一致性了
  • 隔离性
    一个事务不应该受到其他事务的干扰
    以转账的例子而言,当用户A和用户B同时并发的访问数据库,操作账户表(包括账户名–账户金额字段),数据库会为每一个用户的操作开启一个事务,事务和事务之间是相互感知不到的,相互隔离的。
    如果事务的隔离性得不到保障的话就会出现读问题,下文会详细介绍
  • 持久性
    持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

事务的四种隔离级别

  • Read Uncommitted(读取未提交内容)
    所有事务都可以看到其他未提交事务的执行结果
    该级别引发的问题是——脏读(Dirty Read):读取到了未提交的数据
    例:用户A向用户B转账100元,但是不将该操作提交,读未提交的情况下,B查看账户时发现钱确实已到账,但用户A转账这个操作只要不提交,事务就会被回滚,之后B再查看账户时会发现钱没到账,这也就是出现了脏读。

  • Read Committed(读取提交内容)
    这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)
    这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。
    导致这种情况的原因可能有:
    有一个交叉的事务有新的commit,导致了数据的改变;
    第一次
    start transaction
    A: select money form account where id = 1;(事务开启)
    结果mondy:20
    B: update account set money=10 where id=1;(事务开启)
    B: commit(提交)
    第二次 在事务结束之前
    A: select money form account where id = 1; 读到了B事务更新的数据
    发现结果是10
    这样就出现了两次读数据结果不一样

  • repeatable 重复读
    重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
    这样可以避免前面读提交中不可以避免的不可重复读,因为不再允许修改操作,但是不可以避免幻读,因为并没有不允许插入操作。

  • serializable 可串行化
    可串行化是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值