`
herman_liu76
  • 浏览: 100024 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

spring中service事务配置传播隔离等关系

阅读更多
    工作中正好碰到这个问题,于是学习以下两个文章。先介绍了一些知识。后加入了对知识的分析,方便理解。并对可能的原理进行推测,以后有空看源码。
    文章一
    文章二

    做java的WEB开发,通常都是分层的,包括action(controller层),service层,dao层。这里重点说说service层,也就是业务逻辑层的事务问题。

    1.首先说一说action(controller)层
    这一层是与web应用密切相关的,主要是处理request与response。把请求中的东西拿出来,作为业务层的输入,再把业务层的结束包装(处理)后,产生响应对象。

    代码要求:功能分层来说,这个action层功能主要是处理web的数据的,通常是不应该含有事务逻辑的,如果有请另包装到到一个service中。我经常看到一些代码把request传递到service中处理,问过原因,说是参考其它人的代码也是这么写的。所以告诉原因很重要。业务通用性来讲,业务逻辑不一定都是给web用的,总不能让非web的应用,数据包装成request来用吧。

    2.spring注解事务
    我们现在都用注解方式,很多时候只是写一个@Transactional。实际上后面可以设置多种参数。
    有表明传播性与隔离级别。比如:
    @Transactional(propagation = Propagation.REQUIRES_NEW)。不写的情况下,默认是:PROPAGATION_REQUIRED。
    也有表明引起事务回滚的异常类:
    @Transaction(noRollbackFor=RuntimeException.class)
    @Transaction(RollbackFor=Exception.class)
    不写的情况下,默认是:RuntimeException,只回滚unchecked异常。
    另外还有一个readOnly = true,最后会讲。
    默认配置,能够满足正常的需要,没有特殊情况就只要一个@Transaction。但要注意后面提到的异常处理。

    3.关于spring注解事务的异常
    代码要求:按默认情况配置,也就是不配置。自定义业务中异常的时候,让自定义的异常继承自RuntimeException,这样抛出的时候才会被Spring默认的事务处理准确处理。如果是一个servive中产生了checked异常,请在本service方法中处理掉或者另抛出unchecked一场,否则如果有外层service,将不知道要不要回滚整个事务。
    通常我们的项目中,注意异常的处理就可以了。

    以下讨论的回滚都指unchecked异常,先是主要的几种传播与隔离配置。
    3.PROPAGATION_REQUIRED
    一般文章介绍:默认事务类型,如果没有,就新建一个事务;如果有,就加入当前事务。适合绝大多数情况。

    结论:
    内外都无trycatch情况:
    这样在方法中任何地方发生unchecked异常将触发整个方法的回滚。
    无论内外层产生unchecked异常,都回滚。

    如果有trycatch情况:
    外层发生了unchecked异常,但被外层trycatch了,那是不会回滚的。
    内层发生了unchecked异常,但外层有trycatch,但还是回滚了。按说外层的AOP是感受不到抛出的异常的,怎么会回滚呢?我猜测是内层的AOP也抛出了一个不能被外层trycatch的异常,而被外层的AOP感受到了。
    内层发生了unchecked异常,但内层有trycatch,内层不回滚,如果外层正常,也不回滚了。


    4.PROPAGATION_NESTED
    一些文章先测试再讲规则,有点不知其所以然的感觉,所以我先查查什么是嵌套事务及其原则?
    嵌套事务是一个外部事务的一个子事务,是一个外部事务的一个组成部分,当嵌套事务发生异常而回滚,则会恢复到嵌套事务的执行前的状态,相当于嵌套事务未执行。
    如果外部事务回滚,则嵌套事务也会回滚!!!外部事务提交的时候,嵌套它才会被提交。
    定义明确了,无论是交给spring处理NESTED事务,还是数据库处理NESTED事务,或者你设计什么事务时,原则都应该一样。

     当所调用的方法为NESTED事务,该事务的回滚可以不影响到调用者的事务
     当然如果子事务没有trycatch,异常冒泡而出,就将触发调用者事务的回滚。子事务有了trycatch就不会影响到外部调用者事务了,不会触发整个方法的回滚。

    而调用者出现unchecked异常,却能触发所调用的nested事务的回滚!

    5.PROPAGATION_REQUIRES_NEW
    更少用到了此情况,通常可以将此部分代码放在事务之外执行 实在剥离不开才会用到。当被调用时,就相当于暂停(挂起)当前事务,先开一个新的事务去执行REQUIRES_NEW的方法,如果REQUIRES_NEW中的异常得到了处理那么他将不影响调用者的事务,同时,调用者之后出现了异常,同样也不会影响之前调用的REQUIRES_NEW方法的事务.
    有个猜测:但是如果如果内部REQUIRES_NEW中的异常没有处理,异常冒泡会影响到调用者吧!
  
    6.REQUIRES_NEW与NESTED比较
    PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, REQUIRES_NEW 完全是一个新的事务,而NESTED 则是外部事务的子事务,如果外部事务commit,嵌套事务也会被commit, 这个规则同样适用于rollback。
    PROPAGATION_NESTED可以在外层rollback所有内层的事务。REQUIRES_NEW不行。

    后面再介绍几个配置参数,简单介绍就明白了。
    7.PROPAGATION_SUPPORTS:如果没有,就以非事务方式执行;如果有,就使用当前事务。

    8.PROPAGATION_NOT_SUPPORTED:如果没有,就以非事务方式执行;如果有,就将当前事务挂起。即无论如何不支持事务。
    例子如下面的文章:微信文章
    上面的文章中,介绍了一个事务的业务中,突然要加一个非事务的方法。非事务的方法不能是本对象里的方法,不能是private方法,只能是public的,而且只有另写对象,以注入的方式,才能实现事务之间的关系处理。因为AOP代理了这些方法所在的业务对象。

    9.PROPAGATION_NEVER:如果没有,就以非事务方式执行;如果有,就抛出异常。

    10.PROPAGATION_MANDATORY:如果没有,就抛出异常;如果有,就使用当前事务。

    11.引伸的配置@Transactional(readOnly = true)
    从这一点设置的时间点开始(时间点a)到这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!(查询中不会出现别人在时间点a之后提交的数据)。
    应用场合:
    如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;
    如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。
    【注意是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务】
    在将事务设置成只读后,相当于将数据库设置成只读数据库,此时若要进行写的操作,会出现错误。

    项目中的使用情况:目前的项目几乎没有实时的,多条相关的只读查询,不需要这个设置。

    注:以上的总结都没有时间亲测,只是看一些文章的总结。如有错误,欢迎指正。

-------------------------------------------------------------------------
    另记录一个问题解决:之前部署的一个应用,平时正常,但经常早上不能访问,很是着急,上班前要花时间远程处理。发现是应用服务器与数据库服务器的网线直连不通了,时间紧就重启下。后来发现只要网络禁用再启动就行了。
    后来几次后没找到原因,没条件换硬件或者不断修改配置来测试。突然想到定时任务,于是查到可以自动禁用启用网络的命令。至此,这个麻烦的问题再也没出现过了。

  • 大小: 47.9 KB
分享到:
评论

相关推荐

    spring几种事务配置详解【精】

    本文将深入探讨Spring中的几种事务配置方式,帮助开发者更好地理解和运用。 1. **编程式事务管理** 编程式事务管理是在代码中显式调用事务API来控制事务的开始、提交、回滚等操作。这种方式直接在业务逻辑代码中...

    Spring声明式事务配置管理方法

    以下是关于Spring声明式事务配置管理的详细说明: 1. **事务管理器配置**: 在`/WEB-INF/applicationContext.xml`文件中,我们需要定义一个事务管理器Bean。通常,对于Hibernate,我们会使用`...

    spring3.0两种事务管理配置

    这种方法只需要在 Spring 配置文件中定义一个事务管理对象(如 DataSourceTransactionManager),然后加入 `<tx:annotation-driven/>` 节点,引用该事务管理对象,然后即可在需要进行事务处理的类和方法使用 `@...

    Spring事务配置的五种方式

    Spring 事务配置是Spring框架中不可或缺的部分,它用于管理和协调应用程序中的事务边界,确保数据的一致性和完整性。...在使用过程中,还需注意事务的隔离级别、传播行为、回滚规则等事务特性,确保事务管理正确无误。

    spring 事务传播

    ### Spring 事务传播属性详解 #### 一、Spring 事务基础概述 在深入探讨Spring框架中的事务传播属性...此外,需要注意的是,在实际开发中,还应结合事务的隔离级别、读写锁等其他高级特性来进一步优化事务管理策略。

    spring 的3种事务配置方式

    本文将详细介绍Spring中的三种事务配置方式:编程式事务管理、声明式事务管理以及基于注解的事务管理。 **1. 编程式事务管理** 编程式事务管理是通过编程的方式手动控制事务的开始、提交、回滚等操作。主要使用`...

    Spring 事务 (二) Spring 声明式事务 配置

    5. **事务配置**:在Spring XML配置文件中,我们需要配置事务管理器,例如DataSourceTransactionManager用于JDBC事务,HibernateTransactionManager用于Hibernate事务。同时,还需要开启事务代理,如下所示: ```...

    spring与mybatis整合实现事务配置

    4. **事务配置**:在Spring中,事务管理有两种方式:编程式事务管理和声明式事务管理。通常我们采用声明式事务管理,通过`<tx:annotation-driven>`标签启用基于注解的事务管理。事务的传播行为、隔离级别、超时时间...

    Spring声明式事务配置模板2.x

    3. **@Transactional注解**:在Java代码中,我们可以在Service层或者DAO层的方法上使用`@Transactional`注解,指定事务的属性,如传播行为、隔离级别、超时时间等。例如: ```java @Service public class ...

    Spring基于XML方式配置事务

    在提供的压缩包文件`Spring-JDBC`中,可能包含Spring与JDBC集成的相关示例,比如数据库连接池配置、JdbcTemplate的使用等,这些都是在Spring环境中进行事务管理的基础。通过理解并实践这些配置,你可以更好地掌握...

    spring声明式事务配置方法.docx

    以下是关于Spring声明式事务配置方法的详细解释。 首先,Spring声明式事务管理主要依赖于AOP(面向切面编程)实现。通过在配置文件中定义事务的规则,Spring可以在特定的方法执行前后自动地进行事务的开启、提交、...

    在Spring中配置Hibernate事务

    在需要进行事务处理的业务层方法上添加@Transactional注解,指定事务属性如传播行为、隔离级别、读写模式等。例如: ```java @Service public class UserService { @Transactional public void addUser(User ...

    Spring的事务配置的五种方式

    Spring框架在处理事务时提供了五种不同的配置方式,这些配置主要涉及到事务的声明式管理和编程式管理。在Spring中,事务管理通常分为三部分:...在实际应用中,应根据项目需求和性能考虑选择合适的事务配置方式。

    Spring使用XML配置声明式事务

    这个标签告诉Spring容器自动检测带有@Transactional注解的类,并根据注解中的属性进行事务配置。 接下来,我们需要配置数据源和事务管理器。数据源(DataSource)是连接到数据库的资源,Spring提供了多种数据源实现...

    基于Spring JDBC的事务管理

    本资源主要介绍基于Spring JDBC的事务管理,包括事务的定义、使用 @Transactional 注解、Spring JDBC的事务管理机制、事务的ACID特性、事务的传播、事务的隔离等内容。 事务的定义 事务是一种数据库中能够保证一...

    Spring使用TransactionProxyFactoryBean声明式事务配置实例

    2. **定义事务策略**:我们需要在TransactionProxyFactoryBean的配置中指定事务管理器(如DataSourceTransactionManager或JtaTransactionManager),并设置相应的事务属性,如隔离级别、传播行为、回滚规则等。...

    spring mvc 事务配置+异常处理

    `@Transactional`是Spring提供的一个注解,可以标记在类或方法级别,用于声明事务的属性,如传播行为、隔离级别、读写模式等。例如: ```java @Service public class UserService { @Transactional public void ...

    Spring中的四种声明式事务的配置

    在Spring框架中,声明式事务管理是通过AOP(面向切面编程)实现的,它允许开发者无需在业务代码中显式处理事务,而是通过配置来控制事务的边界。Spring提供了四种不同的方式来配置声明式事务,这使得事务管理更加...

Global site tag (gtag.js) - Google Analytics