• 数据库事务隔离级别


    一、什么是数据库事务

    所谓数据库事务是指针对数据库的某一组操作要么全部成功,要么全部失败。

    二、数据库事务的四个特性

    事务的四个特性就是常说的ACID,对应的英文及汉语意思分别是:

    原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持久性( Durability )

    三、事务的隔离性

    我们先看一下如果不考虑事务的隔离性会出现的问题

    a、脏读

    所谓的脏读是指一个事务T1读到了事务T2未提交的数据,如果T2的事务最后不提交,那么T1再后来读到的数据跟前一次是不一样的

    b、不可重复读

    所谓的不可重复读是指一个事务T1读事务T2的数据,多次内数据不一样

    c、幻读(虚读)

    所谓的幻读是指事务T1对自己某一项的数据全部修改后T2又对数据进行修改,T1在读会发现有一条不一样

    针对这些问题,就有了不同的事务隔离级别,下面用一张表进行说明

    注意:这是针对Mysql的事务隔离级别,而oracle只有Read Commited 和Serializable两种。Mysql的默认隔离级别是Repeatable read,Oracle则是Read comiitted。

    下面通过一些比较生活化的例子来解释一下事务的隔离级别:

    Read uncommitted 读未提交


    公司发工资了,领导把5000元打到singo的账号上,但是该事务并未提交,而singo正好去查看账户,发现工资已经到账,是5000元整,非常高兴。可是不幸的是,领导发现发给singo的工资金额不对,是2000元,于是迅速回滚了事务,修改金额后,将事务提交,最后singo实际的工资只有2000元,singo空欢喜一场。

    出现上述情况,即我们所说的脏读,两个并发的事务,“事务A:领导给singo发工资”、“事务B:singo查询工资账户”,事务B读取了事务A尚未提交的数据。


    当隔离级别设置为Read uncommitted时,就可能出现脏读,如何避免脏读,请看下一个隔离级别。




    Read committed 读提交


    singo拿着工资卡去消费,系统读取到卡里确实有2000元,而此时她的老婆也正好在网上转账,把singo工资卡的2000元转到另一账户,并在singo之前提交了事务,当singo扣款时,系统检查到singo的工资卡已经没有钱,扣款失败,singo十分纳闷,明明卡里有钱,为何......


    出现上述情况,即我们所说的不可重复读,两个并发的事务,“事务A:singo消费”、“事务B:singo的老婆网上转账”,事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。


    当隔离级别设置为Read committed时,避免了脏读,但是可能会造成不可重复读。


    如何解决不可重复读这一问题,请看下一个隔离级别。




    Repeatable read 重复读


    当隔离级别设置为Repeatable read时,可以避免不可重复读。当singo拿着工资卡去消费时,一旦系统开始读取工资卡信息(即事务开始),singo的老婆就不可能对该记录进行修改,也就是singo的老婆不能在此时转账。


    虽然Repeatable read避免了不可重复读,但还有可能出现幻读。singo的老婆工作在银行部门,她时常通过银行内部系统查看singo的信用卡消费记录。有一天,她正在查询到singo当月信用卡的总消费金额(select sum(amount) from transaction where month = 本月)为80元,而singo此时正好在外面胡吃海塞后在收银台买单,消费1000元,即新增了一条1000元的消费记录(insert transaction ... ),并提交了事务,随后singo的老婆将singo当月信用卡消费的明细打印到A4纸上,却发现消费总额为1080元,singo的老婆很诧异,以为出现了幻觉,幻读就这样产生了。





    Serializable 串行读


    Serializable是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读。

  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Mysql 使用 select into outfile
    Mysql 使用CMD 登陆
    使用Clean() 去掉由函数自动生成的字符串中的双引号
    Get Resultset from Oracle Stored procedure
    获取引用某个主键的所有外键的表
    Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
    添加MySql Metat Database 信息
    at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
  • 原文地址:https://www.cnblogs.com/yunqing/p/7722257.html
Copyright © 2020-2023  润新知