spring boot项目实战Spring-BootSpring Boot

spring boot实战之事务

2017-09-30  本文已影响319人  思与学

事务在项目里也是不可或缺的一部分,建议形成一个统一的事务管理规范,不要出现让程序员根据业务自行添加,团队成员能力有高有低,很容易就出现需要事务时没添加事务,这种问题又很难测试出来,运行时却会不定时出现数据的不一致。
想实现类似原spring项目里通过aop方式配置事务的效果,各种尝试,目前还未找到十分可行的方式。测试可用的事务配置方式有两种:在service上添加@Transactional注解 和 引入xml配置文件(不推荐),建议使用@Transactional注解来进行事务配置。

1、@Transactional实现事务

spring boot项目内使用事务最简单直接的方式就是在每个service类上添加@Transactional注解,即可自动开启对事务的支持,不需要进行额外操作。

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED)

该注解也可添加在方法上,对事物进行更精细化的管理,注意引用spring包下的,不要引用javax包下的

2、引入xml配置实现事务

1、 创建com.onecoderspace.transaction.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"
    default-lazy-init="false" default-autowire="no">

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />
    <!-- 对于service使用annotation声明事物 -->
    <tx:annotation-driven mode="proxy" proxy-target-class="true" transaction-manager="transactionManager" order="100" />
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" isolation="REPEATABLE_READ" />
            <tx:method name="save*" isolation="REPEATABLE_READ" />
            <tx:method name="update*" isolation="REPEATABLE_READ" />
            <tx:method name="del*" isolation="REPEATABLE_READ" />
            <tx:method name="do*" isolation="REPEATABLE_READ" />
            <tx:method name="*" isolation="REPEATABLE_READ" read-only="true" />
        </tx:attributes>
    </tx:advice>
    
    <aop:config proxy-target-class="true">
        <aop:advisor pointcut="execution(* com.onecoderspace..*.service..*.*(..))" advice-ref="txAdvice" order="200" />
    </aop:config>
</beans>

2、引入xml配置文件

@Configuration
@ImportResource("classpath:com.onecoderspace.transaction.xml")
public class AopTransactionConfig {
    
}

3、小结

  1. service层需要统一添加事务,避免部分人员忘记事务处理,在运行过程中导致数据不一致;
  2. 在每个service上添加注解实现事务:定好项目整体事务隔离级别和传播属性即可在项目级别形成规范,胜在简单,可执行性更高,目前本公司使用该方式;
  3. 在service方法上添加注解实现事务:事务管理更灵活,更有针对性,缺点是难以形成统一规范,依赖编程人员的经验和能力,如果团队内存在经验不很充足的成员不推荐使用该方式;
  4. 通过引入xml配置实现事务:配置简单,在xml内一处配置即可实现事务管理,耦合性更低;缺点就是使用了xml配置,因此不太推荐使用该方式;
  5. 隔离级别(isolation)通常选择REPEATABLE_READ;传播属性通常使用默认值(REQUIRED)即可。

4、扩展阅读

隔离级别(isolation)

隔离级别是指若干个并发的事务之间的隔离程度,与我们开发时候主要相关的场景包括:脏读取、重复读、幻读。

我们可以看 org.springframework.transaction.annotation.Isolation 枚举类中定义了五个表示隔离级别的值:

public enum Isolation {  
    DEFAULT(-1),
    READ_UNCOMMITTED(1),
    READ_COMMITTED(2),
    REPEATABLE_READ(4),
    SERIALIZABLE(8);
}

传播属性(propagation)

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。

我们可以看 org.springframework.transaction.annotation.Propagation 枚举类中定义了6个表示传播行为的枚举值:

public enum Propagation {  
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
}

如有更好实现方式,敬请指出。

《spring boot项目实战》之事务使用,本人搭建好的spring boot web后端开发框架已上传至GitHub,欢迎吐槽!
https://github.com/q7322068/rest-base,已用于多个正式项目,当前可能因为版本问题不是很完善,后续持续优化,希望你能有所收获!

上一篇 下一篇

猜你喜欢

热点阅读