JAVA事务简述及Spring传播属性测试验证

    1.什么是Java事务?
        要么全部执行成功,要么全部执行失败。
        事务必须服从ACID原则。原子性(atomic)、一致性(consistency)、隔离性(isolation)和持久性(durability)
        原子性:表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。
        一致性:当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。
        隔离性:在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。
        持久性:表示已提交的数据在事务执行失败时,数据的状态都应该正确。

2、Java事务的类型
        1)JDBC事务:Connection对象控制,自动提交和手动提交:局限于一个数据库连接。
        java.sql.Connection提供控制事务的方法:
            public void setAutoCommit(boolean);
            public boolean getAutoCommit();
            public void commit();
            public void rollback();
        事务隔离级别:
            TRANSACTION_NONE_JDBC:驱动不支持事务
            TRANSACTION_READ_UNCOMMITTED :读未提交;允许脏读、不可重复读和幻读
            TRANSACTION_READ_COMMITTED:读已提交;禁止脏读,但允许不可重复读和幻读
            TRANSACTION_REPEATABLE_READ:可重读;禁止脏读和不可重复读,但允许幻读
            TRANSACTION_SERIALIZABLE:禁止脏读、不可重复读和幻读
            
            脏读:一个事务读到了另一个事务未提交的数据。
            不可重复读:一个事务的操作导致另一个事务前后两次读到不同的数据
            幻读:一个事务的操作导致另一个事务前后两次读到的结果数据量不同

3、Spring事务

        1)隔离级别:
                ISOLATION_DEFAULT:使用数据库默认的事务隔离级别
                ISOLATION_READ_UNCOMMITTED:事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
                ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。
                ISOLATION_REPEATABLE_READ:这种事务隔离级别可以防止脏读,不可重复读,但是可能出现幻读。
                ISOLATION_SERIALIZABLE:最高代价,但是最可靠的事务隔离级别。事务被处理为顺序执行
         2)Spring事务传播属性

            PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。
            PROPAGATION_REQURES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
            PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
            PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
            PROPAGATION_NOT_SUPPORT:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
            PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常
            PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则则按照Required属性执行。

      3)事务嵌套使用时的规则测试记录

测试记录
    1、执行不带事务的方法ServiceA,调用传播属性为Required方法ServiceB,没有异常,全部执行插入成功
    2、执行不带事务的方法ServiceA,调用传播属性为Required方法ServiceB,ServiceB抛出异常未捕获,A执行成功,B执行失败
    3、执行不带事务的方法ServiceA,调用传播属性为Required方法ServiceB,ServiceB抛出异常捕获,A执行成功,B执行失败
    4、执行不带事务的方法ServiceA,调用传播属性为Required方法ServiceB,ServiceA抛出异常,A执行成功,B执行成功
    结论:不带事务的方法,抛出异常前都会执行,且不会回滚,调用的带Required属性的方法失败不会影响调用方法
    
    1、执行默认Required属性的方法ServiceA,调用Nest属性且抛出异常的方法ServiceB,然后调用Required属性的ServiceC,未捕获异常,A、B、C均执行失败
    2、执行默认Required属性的方法ServiceA,调用Nest属性且抛出异常的方法ServiceB,然后调用Required属性的ServiceC,捕获异常,B执行失败,A、C执行成功
    3、执行默认Required属性的方法ServiceA且出现异常,调用Nest属性且抛出异常的方法ServiceB,然后调用Required属性的ServiceC,捕获异常,A、B、C均执行失败
    4、执行默认Required属性的方法ServiceA且出现异常,调用Nest属性方法ServiceB,然后调用Required属性的ServiceC,捕获异常,A、B、C均执行失败
    5、执行默认Required属性的方法ServiceA且出现异常且捕获,调用Nest属性方法ServiceB,然后调用Required属性的ServiceC,A、B、C均执行成功
    结论:事务传播属性为Required的方法调用Nest属性的方法,Nest属性方法抛出异常未捕获会导致原调用回滚,捕获异常则不影响调用方,如果调用方抛出异常则全部回滚,调用方捕获异常则全部成功。
    
    1、    执行默认Required属性的方法ServiceA,调用Requires_new属性且抛出异常的方法ServiceB,然后调用Required属性的ServiceC,捕获异常,A执行成功,B执行失败
    2、    执行默认Required属性的方法ServiceA,调用Requires_new属性且抛出异常的方法ServiceB,然后调用Required属性的ServiceC,未捕获异常,A、B执行失败
    3、    执行默认Required属性的方法ServiceA,调用Requires_new属性方法ServiceB,然后调用Required属性的ServiceC,A抛出异常,A执行失败、B执行成功
    结论:事务传播属性Requires调用Requires_new方法,requiresNew捕获异常则不影响调用方法,未捕获则影响调用方导致回滚,调用方异常不影响requiresNew属性方法的执行
    
    1、执行Required属性的方法ServiceA,调用Required属性且抛出异常的方法ServiceB,未捕获了异常,A、B执行失败
    2、执行Required属性的方法ServiceA,调用Required属性且抛出异常的方法ServiceB,捕获了异常,A、B执行失败
    3、执行Required属性的方法ServiceA,调用Required属性方法ServiceB,调用方抛出异常捕获了异常,A、B执行成功
    4、执行Required属性的方法ServiceA,调用Required属性方法ServiceB,调用方抛出异常未捕获了异常,A、B执行失败
    
    结论:事务传播属性Required调用Required属性方法,被调用方异常不管有没有捕获都会导致全部回滚。调用方异常捕获则均成功,未捕获则均失败

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值