• spring3 事务处理


    先让我们看代码吧!
    以下代码为在“Spring3事务管理——基于tx/aop命名空间的配置”基础上修改。首先修改applicationContext.xml如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <!-- 定义一个数据源 -->
    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/spring_test" />
            <property name="username" value="root" />
            <property name="password" value="root" />
    </bean>
     
    <!-- 定义JdbcTemplate的Bean -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
            p:dataSource-ref="dataSource">
    </bean>
     
    <!-- 配置事务管理器 -->
    <bean id="txManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
            p:dataSource-ref="dataSource">
    </bean>
     
    <!-- enables scanning for @Transactional annotations -->
    <tx:annotation-driven transaction-manager="txManager" />
     
    <!-- 在该Bean的代码中标注@Transactional可以被事务管理器注入 -->
    <bean id="userScore"
            class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"
            p:userScoreRepository-ref="userScoreRepository_jdbc" />
     
    <bean id="userScoreRepository_jdbc"
            class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"
            p:jdbcTemplate-ref="jdbcTemplate" />

     实现类代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Transactional
    public class UserScoreRepositoryImpl implements UserScoreRepository {
     
        private JdbcTemplate jdbcTemplate;
     
        @Override
        public UserScore getUserSocore(String userNo) {
     
        final UserScore us = new UserScore();
        ...
        return us;
        }
        ...
     
    }

    OK了!以上就实现了简单的事务管理了。现在再稍微了解下@Transactional。
    在配置文件中,默认情况下,<tx:annotation-driven>会自动使用名称为transactionManager的事务管理器。所以,如果定义的事务管理器名称为transactionManager,那么就可以直接使用<tx:annotation-driven/>。如下:

    1
    2
    3
    4
    5
    6
    7
    8
    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        p:dataSource-ref="dataSource">
    </bean>
     
    <!-- enables scanning for @Transactional annotations -->
    <tx:annotation-driven/>

    <tx:annotation-driven>一共有四个属性如下,

    • mode:指定Spring事务管理框架创建通知bean的方式。可用的值有proxy和aspectj。前者是默认值,表示通知对象是个JDK代理;后者表示Spring AOP会使用AspectJ创建代理
    • proxy-target-class:如果为true,Spring将创建子类来代理业务类;如果为false,则使用基于接口的代理。(如果使用子类代理,需要在类路径中添加CGLib.jar类库)
    • order:如果业务类除事务切面外,还需要织入其他的切面,通过该属性可以控制事务切面在目标连接点的织入顺序。
    • transaction-manager:指定到现有的PlatformTransaction Manager bean的引用,通知会使用该引用

     @Transactional的属性

    属性名

    类型

    说明

    isolation

    枚举org.springframework.transaction.annotation.Isolation的值

    事务隔离级别

    noRollbackFor

    Class<? extends Throwable>[]

    一组异常类,遇到时不回滚。默认为{}

    noRollbackForClassName

    Stirng[]

    一组异常类名,遇到时不回滚,默认为{}

    propagation

    枚举org.springframework.transaction.annotation.Propagation的值

    事务传播行为

    readOnly

    boolean

    事务读写性

    rollbackFor

    Class<? extends Throwable>[]

    一组异常类,遇到时回滚

    rollbackForClassName

    Stirng[]

    一组异常类名,遇到时回滚

    timeout

    int

    超时时间,以秒为单位

    value

    String

    可选的限定描述符,指定使用的事务管理器

    @Transactional标注的位置
    @Transactional注解可以标注在类和方法上,也可以标注在定义的接口和接口方法上。
    如果我们在接口上标注@Transactional注解,会留下这样的隐患:因为注解不能被继承,所以业务接口中标注的@Transactional注解不会被业务实现类继承。所以可能会出现不启动事务的情况。所以,Spring建议我们将@Transaction注解在实现类上。
    在方法上的@Transactional注解会覆盖掉类上的@Transactional。

    使用不同的事务管理器
    如果我们要程序中使用多个事务管理器(主要是针对多数据源的情况),可以通过以下的方式实现:
    Service代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class MultiTxService {
        @Transactional("tran_1")
        public void addTest(int id){
             
        }
        @Transactional("tran_2")
        public void deleteTest(int id){
             
        }
     
    }

    applicationContext.xml配置如下: 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <bean id="tran_1"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        p:dataSource-ref="dataSource">
        <qualifier value="tran_1"/>
    </bean>
    <bean id="tran_2"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        p:dataSource-ref="dataSource">
        <qualifier value="tran_2"/>
    </bean>

    经过以上的代码,每个事务都会绑定各自的独立的数据源,进行各自的事务管理。我们可以优化下以上代码,可以自定义一个绑定到特定事务管理器的注解,然后直接使用这个自定义的注解进行标识:

    1
    2
    3
    4
    5
    6
    @Target({ElementType.METHOD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Transactional("tran_1")
    public @interface CustomerTransactional {
     
    }

    在Service代码中使用:

    1
    2
    3
    4
    5
    6
    7
    ...
    //使用名为tran_1的事务管理器
    @CustomerTransactional
    public void addTest(String str){
         
    }

    转自:http://my.oschina.net/guanzhenxing/blog/214228

    ORM用JPA的事务处理:

    2.  使用@Transactional的Spring配置

         为了使用基于@Transactional的事务管理,需要在Spring中进行如下的配置:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1.    <beans:bean id="transactionManager"  
    2.     class="org.springframework.orm.jpa.JpaTransactionManager">  
    3.     <beans:property name="dataSource" ref="dataSource" />  
    4.     <beans:property name="entityManagerFactory" ref="entityManagerFactory" />  
    5. </beans:bean>  
    6.   
    7. <!-- 声明使用注解式事务 -->  
    8. <tx:annotation-driven transaction-manager="transactionManager" />  

        dataSource是在Spring配置文件中定义的数据源的对象实例,EntityManagerFactory是基于JPA使用的实体类管理器:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean。这些都是用来配置与数据库的连接信息,本质上,@Transactional使用了JDBC的事务来进行事务控制的。

        <annotation-driven>标签的声明,则是在Spring内部启用@Transactional来进行事务管理,类似开关之类的声明。

  • 相关阅读:
    UVA——A Spy in the Metro(线性dp)
    IDEA运行jsp文件变成源码详细解决方案
    CF1105C Ayoub and Lost Array(dp+矩阵快速幂优化)
    牛客练习赛75——A广义肥波
    void * 指针和const 指针
    详解getchar()函数与缓冲区
    深入了解scanf() getchar()和gets()等函数之间的区别
    字符串和指针注意
    指针
    数组和字符串的小结
  • 原文地址:https://www.cnblogs.com/smile0120/p/5163110.html
Copyright © 2020-2023  润新知