精华内容
下载资源
问答
  • 查看事务隔离级别 在 MySQL 中,可以通过show variables like ‘%tx_isolation%’或select @@tx_isolation;语句来查看当前事务隔离级别。 查看当前事务隔离级别的 SQL 语句和运行结果如下: mysql> show variables ...
  • MySQL 四种事务隔离级别详解及对比 按照SQL:1992 事务隔离级别,InnoDB默认是可重复读的(REPEATABLE READ)。MySQL/InnoDB 提供SQL标准所描述的所有四个事务隔离级别。你可以在命令行用–transaction-isolation选项...
  •  我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式。同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力。所以...
  • SQL标准定义了四种隔离级别隔离级别从低到高分别是:Read uncommitted 、Read committed 、Repeatable read 、Serializable。在各个隔离级别上被禁止出现的现象是: 脏读:一个事务读取了另一个并行未提交事务写入...
  • 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 代码如下: #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. [mysqld] transaction-...
  • 查询:默认事务隔离级别 mysql> select @@tx_isolation;当前会话的默认事务隔离级别 mysql> select @@session.tx_isolation;当前会话的默认事务隔离级别 mysql> select @@global.tx_isolation;全局的事务隔离级别
  • 好久没碰数据库了,只是想起自己当时在搞数据库的时候在事务隔离级别这块老是卡,似懂非懂的。现在想把这块整理出来,尽量用最简洁的语言描述出来,供新人参考。 首先创建一个表 account。创建表的过程略过(由于 ...
  • 数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为 Read uncommitted:允许脏读。 Read committed: 防止脏读,最常用的隔离级别,并且是大多数数据库的默认隔离级别。 Repeatable read:可以防止脏...
  • 事务隔离级别:一个事务对数据库的修改与并行的另一个事务的隔离程度
  • 52 MySQL是如何支持4种事务隔离级别的?Spring事务注解是如何设置的?l.pdf
  • mysql的四个事务隔离级别 之前在网上查询mysql事务隔离相关资料,一直只是脑子里有一个印象,久而久之还是会忘记,忘记后又要到网上查找相关资料,但是没实践过就对mysql事务隔离级别理解不是特别的深入,现在自己...
  • 主要介绍了Spring事务隔离级别简介及实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
  • MySQL事务隔离级别详解,这个面试经常会面到,必会呀,哈哈
  • 今天小编就为大家分享一篇关于Spring中的事务隔离级别的介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误。设置事务隔离级别将影响整条连接。
  • 前言 ...我们都知道事务的几种性质,数据库中的一致性和隔离性等是实现事务的基本思想,在系统有大量的并发访问的情况下,了解和熟练应用数据库的本身的事务隔离级别,对于写出健壮性,并发处理能力强
  • 项目中,以 Spring 事务为准,因为他重写了数据库的隔离级别,但没有直接修改数据库的隔离级别

    原创博文,欢迎转载,转载时请务必附上博文链接,感谢您的尊重。

    前言

    通过本篇,你将了解到【Spring事务】与【数据库事务】的关系,以及优先级问题,我将为你一一论证。

    阅读本篇,你可能会需要的博文:


    正文

    数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步进行了封装,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制。

    所以说,spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁。

    上面的“总结”来自网络,结合自身理解与实践,的确可以最为一句精华,本文内容主要围绕这句话展开,以2个问题的形式阐明观点。

    1. Spring定义的隔离级别和数据库设置的隔离级别,二者是什么关系?
    2. 如果Spring定义的隔离级别和数据库设置的隔离级别不一样,以谁的为准?

    一、两者的关系

    详情在我的其他博文都有具体介绍(需要的朋友见本文【前言】提示),这里就不赘述了,我们直接对比结果。

    1. 数据库的隔离级别:

    MySQL 默认为 :EPEATABLE_READ;Oracle,sql server 默认为:READ_COMMITTED;READ_UNCOMMITTED 由于隔离级别较低,通常不会被使用。

    √: 可能出现    ×: 不会出现
    隔离级别隔离级别的值脏读不可重复读幻读
    Read uncommitted(未提交读)0
    Read committed(已提交读)1×
    Repeatable read(可重复读)2××
    Serializable(可串行化)3×××

    2. Spring事务的隔离级别:

    Spring事务由 @Transactional 注解实现,隔离级别由它的参数 isolation 控制,Isolation 的 Eum 类中定义了“五个”表示隔离级别的值,如下。

    √: 可能出现    ×: 不会出现
    Isolation的值与隔离级别隔离级别的值脏读不可重复读幻读
    Isolation.DEFAULT0---
    Isolation.READ_UNCOMMITTED1
    Isolation.READ_COMMITTED2×
    Isolation.REPEATABLE_READ4××
    Isolation.SERIALIZABLE8×××

    Isolation.DEFAULT 是 PlatfromTransactionManager 默认的隔离级别,它的含义是:使用数据库默认的事务隔离级别

    除此之外,另外四个与 JDBC 的隔离级别是相对应的,就好像 Java 里的重写一样,所以说:Spring事务隔离级别是在数据库隔离级别之上又进一步进行了封装。

    二、 不一致会怎样

    既然是封装,那么Spring项目应该就是以Spring事务为准的,除非使用 @Transactional(isolation = Isolation.DEFAULT)时,才会使用数据库设置的隔离级别。

    为了验证这个猜想,我们还是找到源码解读一下,从JDBC开始说起吧。

    1. JDBC 加载流程

    每一个 Spring 事务管理,都涉及到了与数据库的交互,也必然涉及到了JDBC连接。

    JDBC 加载的流程还记得吧,肯定都被问过,有四步:注册驱动,建立连接,发起请求,输出结果。写一段伪代码:

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try{
            // 1.注册 JDBC 驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2.创建链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/my_db","root","root");
            // 3.发起请求
            stmt = conn.createStatement();
            String sql = "SELECT id, name, url FROM websites";
            rs = stmt.executeQuery(sql);
            // 4.输出结果
            System.out.print("查询结果:" + rs);
            // 关闭资源(演示代码,不要纠结没有写在finally中)
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se)
            se.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }

    在创建连接阶段,JDBC 从数据库获取一个连接 Connection 对象,该对象不仅有连接数据库的方法,还有设置当前连接的事物隔离级别的方法。

    2. Connection  源码解释

    Connection 实体类中包含了 void setTransactionIsolation(int level) throws SQLException;设置设置当前连接的事物隔离级别的方法。

    Spring 约定了使用 @Transactional 注解的形式实现事务特性,而隔离级别的开启,也是注解的形式实现,如:开启事务的串行级别 —— @Transactional(isolation = Isolation.SERIALIZABLE)。

    源码截不全,我复制一下:

    /**
    * 这是 Connection 连接的部分源码
    */
    public interface Connection  extends Wrapper, AutoCloseable {
    
        ... 
    
        /**
        * 尝试将此连接对象的事务隔离级别更改为给定的级别
        * 接口连接中定义的常量是可能的事务隔离级别
        */
        void setTransactionIsolation(int level) throws SQLException;
    
        ...
    }
    

    该方法的注释说明:尝试将此连接对象的事务隔离级别更改为给定的级别,如果在事务期间调用此方法,则结果由实现定义。

    没错,强调的就是本次连接 Connection,所以,如果spring与数据库事务隔离级别不一致时,以spring为准。

    3. 验证

    阐述一下方法:

    • 首先,验证测试数据库的隔离级别 Select @@tx_isolation;
    • 写一个包含update,save的与测试数据库交互的方法;
    • 分别验证加上@Transactional(isolation = Isolation.SERIALIZABLE)注解前后,测试数据库的隔离级别是否变化!!

    以我的测试数据库为例,结果没有发生变化,都是 READ_COMMITTED。

    这只是简单的验证下Spring事务隔离级别的修改,是否会直接影响数据库的隔离级别,结论是没有。

    不太严谨,但是证明了我的猜想,后期我会在Sping项目中,通过测试代码进一步验证“修改隔离级别以成功运用到Spring事务中”。

    三、总结

    • 数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步进行了封装,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制;
    • 项目中,以 Spring 事务为准,因为他重写了数据库的隔离级别,但没有直接修改数据库的隔离级别;
    • 项目中,如果 Spring 事务隔离级别设置为(isolation = Isolation.DEFAULT)默认数据库优先时,以数据库的隔离级别为准。

    小编怀着忐忑的心情,上传了本篇博文,如果有错误,还请大佬指正!!后期也会补全自己的验证手段!!

    That's all,thank you!


    我是IT无知君,您的点赞、评论和关注,是我创作的动力源泉。
    学无止境,气有浩然,让我们一起加油,天涯未远,江湖有缘再见!!

    展开全文
  • 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。数据库事务的隔离级别有4个,下面话不多说了,来一起看看详细的介绍吧。 数据库事务有四种隔离级别: 未提交读(Read Uncommitted):允许脏...
  • 数据库事务隔离级别

    2011-12-19 14:09:53
    介绍数据库事务的四种隔离级别,比较不同隔离级别的区别和影响
  • 主要介绍了MySQL中Innodb的事务隔离级别和锁的关系讲解教程,来自于美团技术团队的经验实际经验分享,需要的朋友可以参考下
  • 36谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
  • 查询mysql事务隔离级别

    千次阅读 2019-10-11 16:37:59
    3、事务隔离级别越高,越能保证数据的完整性,但是对并发性能影响大,就比如隔离级别为串行化时,读取数据会锁住整张表。 4、不可重复读和幻读很相似,两者整体上都是两次读的数据不相同,但是不可重复读一般时更新...
    转载链接: https://blog.csdn.net/zhuoya_/article/details/80299250

    点击>>MySQL下的存储引擎查看MySQL下的几种存储引擎。在几种存储引擎中,可以看到只有InnoDB存储引擎支持事务,那么本篇就来介绍InnoDB下支持的事务。

    本篇目录

    **************************************************************

    *     事务是什么?                                                                   *

    *     事务遵循的四个特性  (AICD)                                        *

    *     事务中的基本操作                                                            *

    *     事务的四中隔离级别                                                         *

    *     通过设置隔离级别来保证事务的隔离性基本操作                *

    **************************************************************

    一、事务(transaction)

    事务指的就是一种SQL语句的集合。

    二、事务的四个特性


    事务的原子性通过Undo log来保证。(Undo日志记录数据修改前的状态)

    事务的持久性通过Redo log来保证。(Redo日志记录某数据块被修改后的值)

    事务的隔离性通过设置隔离级别来保证。

    事务的一直性通过Redo log来保证。

    三、事务中的基本操作

    (1)回滚:撤销指定SQL语句的功能。

    mysql>rollback;

    (2)提交:将未存储的SQL语句结果写到数据库表中。

    mysql>commit;

    (3)保留点:事务处理中设置的临时占位符。

    mysql>savepoint   XXX;

    注意点:

    1、不能回退select、create和drop语句。

    2、事务提交是默认提交。每执行一条语句就把该语句当成一个事务进行提交。

    3、当出现start transaction;语句时,隐式提交会关闭。

    4、当rollback或者commit语句出现,事务自动关闭,隐式提交自动恢复。

    5、通过设置autocommit=0可以取消自动提交,直到看到autocommit=1才会提交。

    6、如果没有设置保留点,rollback会回滚到start transaction处;如果设置了,并且在rollback指定了该保留点,则回滚到保留点(rollback to XXX)。

    四、事务的四中隔离级别

    在MySQL中有四中隔离级别。每一种隔离级别的作用也不同,下面通过一张表来看一下:

    事务的隔离级别 /  问题脏读不可重复读幻读
    未提交读(read uncommitted)没有避免没有避免没有避免
    已提交读(read committed)已避免没有避免没有避免
    可重复读(repeatable read)已避免没有避免没有避免
    可串行化/可序列化(serializable)已避免已避免

    已避免

    在MySQL中默认的隔离级别是可重复读


    五、设置隔离级来保证事务的隔离性

    该部分结合并发中出现的脏读、不可重复读和幻读来操作。

    (1)

    什么是脏读?


    案例一:未提交隔离级别无法避免脏读。

    a.客户端A开启事务,查询账户余额。


    b.在事务A未提交之前,开启客户端B,更新LIMing的账户余额。


    c.在事务B未提交时,在客户端A查询表中数据,看到了事务B更新的数据。


    d.此时,如果事务B因某些原因需要进行回滚,则所有操作被撤销,A中读到的数据就是脏数据。


    二、

    什么是不可重复读?


    案例二:已提交读避免了脏读,无法避免不可重复读。

    a.客户端A开启事务,查询表中数据。


    b.在事务A还没有提交,开启事务B,更新表中ShangGuan的账户余额。


    c.在事务A中查看ShangGuan的账户余额。余额未该变,说明杜绝了脏读。


    d.事务B提交。


    在事务A中查询账户余额,发生该变。对于开发者来说保证了数据的一致性。但是对于用户来说,两次的读取结果不一样,发生了不可重复读。


    三、

    案例三:可重复读隔离级别避免了不可重复读,但是数据任然保持一致性。

    a.设置隔离级别为可重复读,开启事务A,查询最初的账户余额。


    b.在事务A未提交时,开启事务B,更新表中LiHong的账户余额。


    c.事务B未提交时,在事务A中查询表。发现没有发生变化,避免了不可重复读。


    d.紧接着,在事务A中对LiHong的账户余额做计算,会发现把在事务B中的结果拿来用,在开发人员看来保证了事务的一致性。


    四、

    什么是幻读?


    案例四、可重复读隔离级别下的幻读

    a.在客户端A中开启事务,查询表中数据。


    b.A事务为提交,在客户端B中开启事务,向表中插入一条数据。


    c.在客户端A中计算表中账户余额总和。


    经过操作发现在RPEATABLE-READ隔离级别下并没有发生幻读现象?????

    问号脸,什么原因。

    我查了一下表的存储引擎,如下,是InnoDB存储引擎:


    再查一下,数据库存储引擎


    我忘记了在Linux下的MySQL存储引擎默认是MyISAM存储引擎,它对于非索引项会加表锁。所以查询没出现幻读可能就是这个原因吧。

    在网上查了一下,设置默认存储引擎为InnoDB步骤有:在/etc/my.cnf中,在mysqld后面增加default-storage-engine=INNODB即可。在这儿偷个懒就不验证了。

    五、

    可串行化隔离级别:

    a.在客户端A下设置隔离级别,开启事务。


    b.在A事务未提交时,开启B事务,设置隔离级别,进行插入数据,发现不允许


    ************************************************************************************************************

    总结:

    1、以上操作版本是:

    2、事务的隔离性可通过设置隔离级别来保证。

    3、事务隔离级别越高,越能保证数据的完整性,但是对并发性能影响大,就比如隔离级别为串行化时,读取数据会锁住整张表。

    4、不可重复读和幻读很相似,两者整体上都是两次读的数据不相同,但是不可重复读一般时更新引起的;幻读是插入和删除引起的。

    ***************************************************************************************************************

    展开全文
  • 为什么会出现数据库的隔离级别呢? 数据库隔离级别是为了解决数据库并发访问过程中产生的各种数据安全问题. 事务的基本要素(ACID) 原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能...
  • 在SQL标准中定义了四种隔离级别, 每一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。 下面简单地介绍一下四种隔离级别。 1.READ ...
  • 老实说,事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!因为他们对可重复读(Repeatable Read)和串行化(serializable)的解析实在是看...
  • 仅从ACID或非ACID角度考虑问题是不够的,你应知道你的数据库支持何种事务隔离级别。一些数据库宣称自己具有“最终一致性”,但却可能对重复查询返回不一致的结果。相比于你所寻求的数据库,一些数据库提供更高的事务...
  • 一直没搞清楚spring事务与数据库事务与锁之间的关系。...本人认为事务隔离级别是通过锁的机制实现的,事务隔离级别是数据库开发商根据业务逻辑的实际需要定义的一组锁的使用策略。当我们将数...

    一直没搞清楚spring事务与数据库事务与锁之间的关系。

    spring事务:

    spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁;

    那么事务的隔离级别与锁有什么关系呢?本人认为事务的隔离级别是通过锁的机制实现的,事务的隔离级别是数据库开发商根据业务逻辑的实际需要定义的一组锁的使用策略。当我们将数据库的隔离级别定义为某一级别后如仍不能满足要求,我们可以自定义 sql 的锁来覆盖事务隔离级别默认的锁机制。

    spring事务实际使用AOP拦截注解方法,然后使用动态代理处理事务方法,捕获处理过程中的异常,spring事务其实是把异常交给spring处理;

    spring事务只有捕获到异常才会终止或回滚,如果你在程序中try/catch后自己处理异常而没有throw,那么事务将不会终止或回滚,失去事务本来的作用;

    spring事务会捕获所有的异常,但只会回滚数据库相关的操作,并且只有在声明了rollbackForClassName="Exception"之类的配置才会回滚;

    spring事务会回滚同一事务中的所有数据库操作,本质上是回滚同一数据库连接上的数据库操作;

     

    spring事务总结:

    spring事务本质上使用数据库锁;

    spring事务只有在方法执行过程中出现异常才会回滚,并且只回滚数据库相关的操作;

     

    对象锁和spring事务的对比:

    对象锁可以保证数据一致性和业务逻辑正确性,但不能保证并发性;

    spring事务不能严格保证数据一致性和业务逻辑正确性,但具有较好的并发性,因为只锁数据库行数据;

     

    建议:

    如果只有insert操作,可以使用事务;

    如果涉及update操作但不涉及其他业务逻辑,可以保守使用事务;

    如果涉及update操作及其他业务逻辑,慎用事务,

    并且数据库查询跟数据库更新之间尽量间隔较短,中间不宜插入太多其他逻辑,减少数据一致性的风险;

    对数据一致性要求不高的情况下可以使用事务结合乐观锁,否则建议用锁;

     

    spring事务为什么不能保证数据一致性和业务逻辑正确性:

    1.如果事务方法抛异常,此时会回滚数据库操作,但已经执行的其他方法不会回滚,因此无法保证业务逻辑正确性;

    2.即使事务方法不抛异常,也不能保证数据一致性(因为事务接口里的数据库操作在整个接口逻辑执行结束后才提交到数据 库,在接口最后提交到数据库的前后很有可能带来数据一致性的问题),从而不能保证业务逻辑正确性;

     

    Spring 事务的传播属性

    所谓spring事务的传播属性,就是定义在存在多个事务同时存在的时候,spring应该如何处理这些事务的行为。这些属性在TransactionDefinition中定义,具体常量的解释见下表:

    常量名称常量解释
    PROPAGATION_REQUIRED支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是 Spring 默认的事务的传播。
    PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚之后,不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获,也可以不处理回滚操作
    PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
    PROPAGATION_MANDATORY支持当前事务,如果当前没有事务,就抛出异常。
    PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
    PROPAGATION_NESTED

    如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

    数据库隔离级别

     

    隔离级别隔离级别的值导致的问题
    Read-Uncommitted0导致脏读
    Read-Committed1避免脏读,允许不可重复读和幻读
    Repeatable-Read2避免脏读,不可重复读,允许幻读
    Serializable3串行化读,事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重

    Spring中的隔离级别

     

    常量解释
    ISOLATION_DEFAULT这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。
    ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
    ISOLATION_READ_COMMITTED保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
    ISOLATION_REPEATABLE_READ这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
    ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

    事务管理:

    <!-- 配置事务管理 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<property name="dataSource" ref="dataSource" />
    </bean>

    Spring-mybatis 事务声明方式

    xml配置声明方式:

    <!-- 声明式事务管理 -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    <!-- 声明式事务管理 -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    	<tx:attributes>
    		<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception" />
    		<tx:method name="testTransaction*" propagation="REQUIRED" rollback-for="Exception" read-only="true"/>
    	</tx:attributes>
    </tx:advice>

    事务切入切面:

    <!-- 配置切面 -->
    <aop:config>
    	<aop:pointcut id="transactionPointcut" expression="execution(* com.youx.qd.app.*.dservice.*.*(..))" />
    	<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
    </aop:config>

    测试事务方法:

    @Override
    //@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.SERIALIZABLE,rollbackFor = Exception.class)
    public ResponseDto testTransactionA() {
        System.out.println("开始事务A");
        iTb****Service.update****(1559540272306292637L,2);
        try {
            Thread.sleep(10000L);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("结束事务A");
    
        return null;
    }

    测试结果:表示在事务控制中该操作只允许读取操作

    Spring的事务管理器

    Spring并不直接管理事务,而是提供了多种事务管理器,它们将事务管理的职责委托给JTA或其他持久化机制所提供的平台相关的事务实现。每个事务管理器都会充当某一特定平台的事务实现的门面,这使得用户在Spring中使用事务时,几乎不用关注实际的事务实现是什么。

    Spring提供了许多内置事务管理器实现:

    • DataSourceTransactionManager位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理;
    • JdoTransactionManager位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理;
    • JpaTransactionManager位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理;
    • HibernateTransactionManager位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
    • JtaTransactionManager位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;
    • OC4JjtaTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
    • WebSphereUowTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
    • WebLogicJtaTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。

    声明事务配置分享

    spring中PROPAGATION类的事务属性详解

    1. PROPAGATION_REQUIRED:         支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 

    2. PROPAGATION_SUPPORTS:         支持当前事务,如果当前没有事务,就以非事务方式执行。 

    3. PROPAGATION_MANDATORY:      支持当前事务,如果当前没有事务,就抛出异常。 

    4. PROPAGATION_REQUIRES_NEW:   新建事务,如果当前存在事务,把当前事务挂起。

    5.  PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 

    6. PROPAGATION_NEVER:               以非事务方式执行,如果当前存在事务,则抛出异常。 

    7. PROPAGATION_NESTED:              支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

     

    如何在Spring配置文件中定义事务管理器:

    声明对本地事务的支持:

    a)JDBC及iBATIS、MyBatis框架事务管理器

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    通过dataSource属性指定需要事务管理的单个javax.sql.DataSource对象。在幕后DataSourceTransactionManager通过调用java.sql.Connection来管理事务,而后者是通过DataSource获取到的。通过调用连接的commit()方法来提交事务。同样,事务失败时通过调用rollback()方法进行回滚。

    参考文档:https://www.jianshu.com/p/6b275553b54f

    b)Jdo事务管理器

    <bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager">
        <property name="persistenceManagerFactory" ref="persistenceManagerFactory"/>
    </bean>

    通过persistenceManagerFactory属性指定需要事务管理的javax.jdo.PersistenceManagerFactory对象。

    c)Jpa事务管理器

    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    通过entityManagerFactory属性指定需要事务管理的javax.persistence.EntityManagerFactory对象。

    还需要为entityManagerFactory对象指定jpaDialect属性,该属性所对应的对象指定了如何获取连接对象、开启事务、关闭事务等事务管理相关的行为。

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            ……
            <property name="jpaDialect" ref="jpaDialect"/>
    </bean>
    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

    d)Hibernate事务管理器

    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    在幕后HibernateTransactionManager将事务管理的职责委托给org.hibernate.Transaction对象,而后者是从Hibernate Session中获取到的。当事务成功完成时,HibernateTransactionManager将会调用Transaction对象的commit()方法来提交事务。同样,事务失败时通过调用Transaction的rollback()方法进行回滚。

    Spring对全局事务的支持:

    a)Jta事务管理器

    <beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/jee
           http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
     
      <jee:jndi-lookup id="dataSource" jndi-name="jdbc/test"/>
      <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManagerName" value=" java:comp/TransactionManager"/>
      </bean>
    </beans>
    “dataSource”Bean表示从JNDI中获取的数据源,而txManager是JTA事务管理器,其中属性transactionManagerName指定了JTA事务管理器的JNDI名字,从而将事务管理委托给该事务管理器。
    

    <tx:method/> 有关的设置 

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 142,647
精华内容 57,058
关键字:

事务隔离级别