zoukankan      html  css  js  c++  java
  • 数据库事务

    数据库事务:

    一、事务的四个特征(ACID):原子性、一致性、隔离性、持久性

    1.隔离级别(isolation)

    ①未提交读
    两个同时进行的事务,在a事务数据未提交时,b事务就能读取到a事务带来的数据上的变化,这种隔离级别会造成脏读

    读写提交
    两个同时进行的事务,b事务只能读取a事务提交后的数据,不能读取a事务提交前已变动的数据,但可以读取数据库原有数据。(比如数据库原有5,a事务向其中插入3,在a事务插入之后且提交之前,b事务只能读取原有的5,在提交之后读取的是8),我们可以看到括号中出现了这样的现象,由于我们无法控制b事务的读取点是在a事务提交前还是提交后,b事务的读取操作有可能出现两种结果(5或者8),这种现象我们称为:不可重复读

    ③可重复读

    如果b事务在a事务提交前读的话,系统会禁止其读取,直到a事务提交后,系统才会允许b事务进行读取。这样就解决了b事务读取时会出现两种结果的问题。与此可能出现的问题:幻读。幻读不像上边两种问题那样针对单条数据(解决脏读、不可重复读问题的方法其实是在单条数据上加了锁),它是面向多条数据产生的问题,比如:在a事务开始后且执行sql前,b事务读取了数据的count()总条数,a事务结束后,b事务再次读取数据的count()总条数时,两次读取的结果不一样。

    ④序列化(串行化)

    最严格的隔离级别,事务会按照顺序,一个一个的执行。它不会出现脏读、不可重复读、幻读问题。

    spring采取的默认隔离级别是跟数据库相关的,如:mysql的默认隔离级别为可重复读;oracle的默认隔离级别为读写提交

    二、传播行为(七种)

    ① REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务

    SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务

    MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception

    REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起

    NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起

    ⑥ NEVER:无事务执行,如果当前有事务则抛出Exception

    ⑦ NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样

    三、事务失效场景

    ①spring中事务失效:@Transactional注解使用的是AOP,在使用动态代理的时候只能针对public方法进行代理;

    Spring事务是依靠AOP实现的,在A类的被代理对象的方法中去调用B类代理对象的方法,而如果A类的被代理对象方法中,调用了自身的一个方法,这个方法只是单纯的一个方法而已,并没有经过@Transactional实现AOP,事务失效

    ②在整个事务的方法中使用try-catch,导致异常无法抛出,自然会导致事务失效

    ③rollbackFor属性设置错误/noRollbackFor属性设置错误:指定异常触发回滚,一旦设置错误,导致一些异常不能触发回滚,此时的声明式事务就失效了

    ④propagation属性设置错误:默认的事务传播属性是Propagation.REQUIRED,但是一旦配置了错误的传播属性,也是会导致事务失效,如下三种配置将会导致事务失效:Propagation.SUPPORTS、Propagation.NOT_SUPPORTED、Propagation.NEVER

     ⑤原始ssm项目中,重复扫描导致事务失效:

    在原始的SSM项目中都配置了context:component-scan并且同时扫描了service层,此时事务将会失效。

    按照Spring配置文件的加载顺序来说,会先加载Springmvc的配置文件,如果在加载Springmvc配置文件的时候把service也加载了,但是此时事务还没加载,将会导致事务无法成功生效。

    解决方法:把扫描service层的配置设置在Spring配置文件或者其他配置文件中即可

  • 相关阅读:
    find命令的高级用法之print0及depth
    shell中的单引号和双引号的区别
    基于apache的虚拟主机
    duilib禁止標題欄雙擊放大窗口
    sqlite查询问题,由字母大小写敏感引起
    问题记录,Release模式和Debug运行效果不一样,Release必须加延时
    子函数内malloc分配内存,论如何改变指针参数所指内存,二级指针、三级指针的应用
    如何具体分配一大块堆内存中的各个部分、如何指针转化为地址、如何求指针间地址偏移量(谈谈最近遇到的一个坑爹的接口需求)
    C++ GUID和string转化函数【转载】
    第一次做C++项目的一点小总结
  • 原文地址:https://www.cnblogs.com/qiuyingbo/p/13326814.html
Copyright © 2011-2022 走看看