zoukankan      html  css  js  c++  java
  • 关于事务的总结

    1 spring 事务

     spring默认对应当前数据库的事务,mysql是可重复读Repeatable Read,oracle是读已提交.READ_COMMITTED,

    2 事务的四个隔离级别

          Isolation.DEFAULT:使用底层数据库默认的隔离级别
    • Isolation.READ_UNCOMMITTED:读取未提交数据(会出现脏读,不可重复读)基本不使用
    • Isolation.READ_COMMITTED:读取已提交数据(会出现不可重复读和幻读)
    • Isolation.REPEATABLE_READ:可重复读(会出现幻读)
    • Isolation.SERIALIZABLE:串行化

    3.事务的传播属性

    • PROPAGATION.REQUIRED:如果当前没有事务,则创建一个新事务。如果当前存在事务,就加入该事务。该设置是最常用的设置。
    • PROPAGATION.SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务。如果当前不存在事务,就以非事务执行。
    • PROPAGATION.MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
    • PROPAGATION.REQUIRE_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
    • PROPAGATION.NOT_SUPPORTED:以非事务方式执行操作,如果当前事务存在,就把当前事务挂起。
    • PROPAGATION.NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    • PROPAGATION.NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行

    4 事务失效的几种可能

    1 配置的事务类是否已经交给Spring管理
    2 配置开启事务注解的方法是否为public
    3 是否同一个类中发生了内部方法自调用
    4 是否配置好了事务管理器
    5 异常是否被捕获了
    6 异常类型错误,默认回滚的是RuntimeException,如果想要其他异常也回滚,需要进行手动配置
    7 扩展配置propagation是否配置正确
    8 MySQL数据库引擎是否支持事务(MyIsam引擎不支持事务)
     

    5 几种隔离级别对应的现象

    READ UNCOMMITTED(读未提交数据): 允许事务读取未被其他事务提交的变更数据,会出现脏读、不可重复读和幻读问题。
    READ COMMITTED(读已提交数据): 只允许事务读取已经被其他事务提交的变更数据,可避免脏读,仍会出现不可重复读和幻读问题。
    REPEATABLE READ(可重复读): 确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。
    SERIALIZABLE(序列化): 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,可避免所有并发问题,但性能非常低。

    6 脏读,可重复读,幻读的概念理解

    如果 存在两个事物(T1,T2)同时运行
        脏读: T1读取了已经被T2修改但还未提交的字段,由于某种原因,T2事物回滚,则T1读取的内容是临时且无效的。
       不可重复读: T1读取一个字段,之后T2更新了该字段,T1在此读取该字段值发生了变化。在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(悲观锁),其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。
       幻读: T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行,之后T1在此读取该表会多出几行。读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

    7 几种现象的举例分析说明

    Read uncommitted

    读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。

    事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。

    分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。

    那怎么解决脏读呢?Read committed!读提交,能解决脏读问题。

    Read committed

    读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。

    事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…

    分析:这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。

    那怎么解决可能的不可重复读问题?Repeatable read !

    Repeatable read

    重复读,就是在开始读取数据(事务开启)时,不再允许修改操作

    事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。

    分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

    什么时候会出现幻读?

    事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。


    那怎么解决幻读问题?Serializable!


    Serializable 序列化

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


    值得一提的是:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。

     

  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/zhaoblog/p/15508614.html
Copyright © 2011-2022 走看看