zoukankan      html  css  js  c++  java
  • Spring 与 Mybatis 的事务管理

    问题:Spring 与 Myabatis 整合后,为什么 DAO 不提交事务,但是数据能够插入数据库中?

    1. Mybatis 提供的连接池对象 —> 创建 Connection
      Connection.setAutoCommit(false) 手工的控制了事务,操作完成后,需要手工提交。
    2. Druid(C3P0、DBCP)作为连接池 —> 创建 Connection
      Connection.setAutoCommit(true) 默认值为 true,保持自动控制事务,一条 sql 自动提交。

    答案:因为 Spring 与 Mybatis 整合时,引入了外部连接池对象,保持自动的事务提交这个机制Connection.setAutoCommit(true),不需要手工进行事务的操作,也能进行事务的提交。

    注意:实战中,还是会手工控制事务(多条SQL一起成功,一起失败),后续 Spring 通过 事务控制 解决这个问题

    1. 事务回顾

    事务的 4 大特点: ACID

    • Atomicity 原子性
    • Consistency 一致性
    • Isolation 隔离性
    • Durability 持久性

    如何控制事务?(JDBC、Mybatis)

    JDBC
    Connection.setAutoCommit(false);
    Connection.commit();
    Connection.rollback();
    
    Mybatis

    Mybatis 自动开启事务
    sqlSession.commit();,底层还是调用的 Connection
    sqlSession.rollback();,底层还是调用的 Connection

    2. Spring 中控制事务的开发

    3. Spring 中的事务属性(Transaction Attribute)

    什么是事务属性?

    描述物体特征的一系列值(性别、身高、体重)

    事务属性:描述事务特征的一系列值

    如何添加事务属性?
    @Transactional(isolation=, propagation=, readOnly=,timeout=,rollbackFor,noRollbackFor=,)
    

    隔离属性(ISOLATION)

    描述了事务解决并发问题的特征。
    1. 什么是并发?
      多个事务(用户)在同一时间,访问操作了相同的数据。
      同一时间:0.000 几秒左右
    2. 并发会产生那些问题?
      • 脏读
      • 不可重复读
      • 幻影读
    3. 并发问题如何解决?
      通过隔离属性解决,隔离属性中设置不同过的值,解决并发处理的过程中的问题。
    事务并发产生的问题:
    1. 脏读
      一个事务,读取了另一个事务中没有提交的数据,会在本事务中产生数据不一样的现象
      解决方案:@Transaction(isolation = Isolation.READ_COMMITTED)
    2. 不可重复读
      一个事务中,多次读取相同的数据,但是读取结果不一样,会在本事务中产生数据不一样的现象
      注意:1.不是脏读 2.在一个事务中
      解决方案:@Transaction(isolation = Isolation.REPEATABLE_READ)
      本质:一把行锁(对数据库表的某一行加锁)
    3. 幻影读
      一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题
      解决方案:@Transaction(isolation = Isolation.SERIALIZABLE)
      本质:表锁(对数据库某个表加锁)
    安全与效率对比:
    • 并发安全:SERIALIZABLE > READ_ONLY > READ_COMMITTED
    • 运行效率:READ_COMMITTED > READ_ONLY > SERIALIZABLE
    默认的隔离属性:

    Spring 默认会指定为 ISOLATION_DEFAULT,调用不同数据库所设置的默认隔离属性

    • MySQL:REPEATABLE_READ
    • Oracle:READ_COMMITTED

    查看数据库的默认隔离属性:

    • MySQL:SELECT @@tx_isolation;
    • Oracle:较麻烦,建议百度。

    隔离属性在实验中的建议

    • 推荐使用 Spring 默认指定的 ISOLATION_DEFAULT
    • 未来的实战中,遇到并发访问的情况,很少见
    • 如果真的遇到并发问题,解决方案:乐观锁
      Hibernate(JPA):version
      MyBatis:通过拦截器自定义开发

    传播属性(PROPAGATION)

    概念:描述了事务解决 嵌套问题 的特征。

    事务的嵌套

    指的是一个大的事务中,包含了若干个小的事务。

    事务嵌套产生的问题

    大事务中融入了很多小的事务,他们彼此影响,最终就导致外部大的事务丧失了事务的原子性。

    传播属性的值及其用法:
    传播属性的值 外部不存在事务 外部存在事务 用法 备注
    REQUIRED(默认) 开启新的事务 融合到外部事务中 @Transactional(propagation = Propagation.REQUIRED) 增、删、改方法
    SUPPORTS 不开启事务 融合到外部事务中 @Transactional(propagation = Propagation.SUPPORTS) 查询方法
    REQUIRES_NEW 开启新的事务 挂起外部事务,创建新的事务 @Transactional(propagation = Propagation.REQUIRES_NEW) 日志记录方法中
    NOT_SUPPORTED 不开启事务 挂起外部事务 @Transactional(propagation = Propagation.NOT_SUPPORTED) 极其不常用
    NEVER 不开启事务 抛出异常 @Transactional(propagation = Propagation.NEVER) 极其不常用
    MANDATORY 抛出异常 融合到外部事物中 @Transactional(propagation = Propagation.MANDATORY) 极其不常用
    Spring 中传播属性的默认值是:REQUIRED

    推荐传播属性的使用方式:

    • 增删改 方法:使用默认值 REQUIRED
    • 查询 方法:显示指定传播属性的值为 SUPPORTS

    只读属性(readOnly)

    针对于 只进行查询操作的业务方法,可以加入只读属性,提高运行效率。
    默认值:false

    @Transactional(readOnly = true)
    

    超时属性(timeout)

    指定了事务等待的最长时间。

    为什么事务会进行等待?
    1. 当前事务访问数据时,有可能访问的数据被别的事务进行加锁的处理,那么此时本事务就必须进行等待。
    2. 等待时间:单位是 秒
    3. 如何使用:@Transactional(timeout = 2)
    4. 超时属性的默认值:-1
      -1 表示超时属性由对应的数据库来指定(一般不会主动指定,-1 即可)

    异常属性

    Spring 事务处理过程中:
    • 默认对于 RuntimeException 及其子类,采用 回滚 的策略。
    • 默认对于 Exception 及其子类,采用 提交 的策略。
    使用方法:
    @Transactional(rollbackFor = java.lang.Exception.class, xxx, xxx)
    @Transactional(noRollbackFor = java.lang.RuntimeException, xxx, xxx)
    

    事务属性常见配置总结

    1. 隔离属性:默认值
    2. 传播属性:Required(默认值)增删改、Supports 查询操作
    3. 只读属性:readOnly=false 增删改,true 查询操作
    4. 超时属性:默认值 -1
    5. 异常属性:默认值
    开发建议

    增删改操作:@Transactional
    查询操作:@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)

    没有修不好的电脑
  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/duniqb/p/13274699.html
Copyright © 2011-2022 走看看