zoukankan      html  css  js  c++  java
  • Spring事务

    1、事务的基本概念

    事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

    特点:事务是恢复和并发控制的基本单位。事务应该具有4个属性:原子性、一致性、隔离性、持久性、这四个属性通常称为ACID特性。

    1. 原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。

    2. 一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。(实例:转账,两个账户余额相加,值不变。)

    3. 隔离性(isolation):一个事务的执行不能被其他事务所影响。

    4. 持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

    2、事物的基本原理

    Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring是无法提供事务功能的。

    Spring的事务管理实现原理(已注解方式为例):

    配置文件开启注解驱动,在相关的类和方式上通过注解@Transactional标识。

    Spring在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Trasaction的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。

    真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

    3、Spring事务的传播属性

    常量名称 常量解释
    PROPAGATION_REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务。这是Spring中默认的事务传播。
    PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起
    PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
    PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。
    PROPAGATION_NOT_SUPPORTS 以非事务方式执行,如果当前存在事务,就把当前事务挂起。
    PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
    PROPAGATION_NESTED 如果上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。只对DataSourceTransactionManager事务管理器起效。

    4、数据库隔离级别

    隔离级别 隔离级别的值 导致的问题
    Read-Uncommitted(读未提交) 0 导致脏读
    Read-Committed(读提交) 1 避免脏读,允许不可重复读和幻读
    Repeatable-Read(重复读) 2 避免脏读,不可重复度,允许幻读
    Serializable(序列化) 3 串行化读,事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重。

    脏读:一个事务对数据进行了增删改,但未提交,另一事务可以读到未提交的数据。如果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。

    不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外一个事务对数据进行了修改,这时候两次读取的数据是不一致的。

    幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加了一条数据,这时候第一个事务就会丢失对新增数据的修改。

    总结:

    隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

    大多数的数据库默认隔离级别为Read Committed,比如SqlServer、Oracle

    少数数据库默认隔离级别为:Repeatable Read 比如:MySQL InnoDB

    5、Spring中的隔离级别

    常量 解释
    ISOLATION_DEFAULT 使用后端数据库默认的隔离界别,MySQL默认采用的REPEATABLE_READ隔离级别,Oracle默认采用的READ_COMMITTED隔离级别
    ISOLATION_READ_UNCOMMITTED 最低的隔离级别,允许读取,允许读取尚未提交的的数据变更,可能会导致脏读、幻读或不可重复读。
    ISOLATION_READ_COMMITTED 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
    ISOLATION_REPEATABLE_READ 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
    ISOLATION_SERIALIZABLE 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就说,该级别可以阻止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

    6、事务嵌套

    ServiceA {  
    
        void methodA() {  
            ServiceB.methodB();  
        }  
    
    }  
            
    ServiceB {  
    
        void methodB() {  
        }  
    
    }  
    
    前提:ServiceA的methodA调用内层serviceB的methodB() PROPAGATION_REQUIRED(spring默认)
    
    案例1:当ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED
    
     1、如果ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,会共用同一个事务,如果出现异常,ServiceA.methodA和ServiceB.methodB作为一个整体都将一起回滚。
    
     2、如果ServiceA.methodA没有事务,ServiceB.methodB就会为自己分配一个事务。ServiceA.methodA中是不受事务控制的。如果出现异常,ServiceB.methodB不会引起ServiceA.methodA的回滚。
     
    案例2:当ServiceB.methodB的事务级别PROPAGATION_REQUIRES_NEW,调用ServiceB.methodB,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务。
    
    1、如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。
    
    2、如果ServiceB.methodB失败回滚,如果他抛出的异常被ServiceA.methodA的try..catch捕获并处理,ServiceA.methodA事务仍然可能提交;如果他抛出的异常未被ServiceA.methodA捕获处理,ServiceA.methodA事务将回滚。
    
    案例3:ServiceB.methodB的事务级别为PROPAGATION_NESTED,调用ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的子事务并设置savepoint
    
    1、如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB也将回滚。
    
    2、如果ServiceB.methodB失败回滚,如果他抛出的异常被ServiceA.methodA的try..catch捕获并处理,ServiceA.methodA事务仍然可能提交;如果他抛出的异常未被ServiceA.methodA捕获处理,ServiceA.methodA事务将回滚。
    

    7、Spring事务API架构图

    使用Spring进行基本的JDBC访问数据库有多种选择。

    Spring的两大类工作模式:

    • JDBC Template

      一个在Spring2.5中新提供的SimpleJdbc类能够更好的处理数据库元数据

    • RDBMS Object

      类似JDO的查询设计

    PS:即使选择了其中一种工作模式。依然可以在代码中混用其他任何一种模式以获取带来的好处和优势。

    • JdbcTemplate

    • NamedParameterJdbcTemplate

      对JdbcTemplate做了封装,提供更加便捷的基于命名参数的使用方式而不是传统的JDBC所使用的的“?”作为参数的占位符。该特性必须在JDK1.4以上。

    • SimpleJdbcTemplate

      这个类结合了JDBC Template和NamedParameterJdbcTemplate的最常用的功能,同时他也利用了一些Java 5的特性所带来的优势,例如泛型、varargs和autoboxing,从而提供了更加简便的API访问方式。需要工作在Java 5以上的环境中。

    • SimpleJdbcInsert和SimpleJdbcCall这两个通常和SimpleJdbcTemplate配合使用,需要工作在JDK 5以上,同时数据库需要提供足够的元数据信息。

    1、异常处理

    2、config模块

    3、core模块

    3.1 JdbcTemplate对象
    3.2 RowMapper对象
    3.3 元数据metaData模块
    3.4 使用SqlParameterSource提供参数值
    3.5 simple实现

    4、DataSource

    ​ Spring通过DataSource获取数据库的连接。DataSource是jdbc规范的一部分,他通过ConnectionFactory获取。一个容器和框架可以在应用代码层中隐藏连接池和事务管理。

    ​ 当使用spring的jdbc层,你可以通过JNDI来获取DataSource,也可以通过你自己配置的第三方连接池实现来获取。流行的第三方实现由apache Jakarta Commons dbcp和c3p0.

    ​ TransactionAwareDataSourceProxy作为DataSource的代理类,在对目标DataSource包装的同时,还增加了Spring的事务管理能力。

    ​ 这类几乎很少被用到,除非需要一个标准的JDBC DataSource接口实现作为参数。一般是采用更高层的抽象,比如JdbcTemplate和DataSourceUtils等。

    注意:DriverManagerDataSource仅限测试使用,因为没有提池的功能,会导致多个请求获取连接时性能很差。

    5、object模块

    6、JdbcTemplate

    JdbcTemplate是core包的核心类。

    优点:

    ​ 它帮我们完成了资源的创建以及释放工作,从而简化了我们对JDBC的使用。

    ​ 使用JdbcTemplate进行编码只需要根据明确定义的一组契约来实现回调接口。

    我们可以在DAO实现类中通过传递一个DataSource引用来完成JdbcTemplate的实例化,也可以在Spring的IOC容器中配置一个JdbcTemplate的bean并赋予DAO实现类作为一个实例。需要注意的是DataSource在Spring的IOC容器中总是配置成一个bean,第一种情况下,DataSource bean将传递给service,第二种情况下DataSource bean传递给JdbcTemplate bean。

    7、NamedParameterJdbcTemplate

    ​ 对JdbcTemplate做了封装,提供更加便捷的基于命名参数的使用方式而不是传统的JDBC所使用的的“?”作为参数的占位符。

    分布式事务

    分布式系统的特性(CAP理论)

    数据一致性理解:

    强一致性:当更新操作完成后,任何多个后续进程或线程的访问都会返回最新的更新过的值。对用户友好,需要牺牲可用性。

    弱一致性:系统不会保证后续进程或线程的访问都会返回最新的更新过的值。

    最终一致性:弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS是一个典型的最终一致性系统。

  • 相关阅读:
    http://www.cnblogs.com/zhengyun_ustc/p/55solution2.html
    http://www.cnblogs.com/carekee/articles/1854674.html
    http://www.blogjava.net/xylz/archive/2010/07/08/325587.html
    http://honda418.iteye.com/blog/337052/
    解决myeclipse每次启动注册码过期输入注册码
    JavaScript只能为汉字
    解决 不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接
    websphere变成英文了怎么变回中文
    【技术贴】解决MySql连接不上 ip远程连接Host is not allowed to conn
    【技术贴】解决bug mantisbt APPLICATION ERROR #1502 没有找到类别
  • 原文地址:https://www.cnblogs.com/snail-gao/p/15106302.html
Copyright © 2011-2022 走看看