Spring 4.1 Spring中的事务处理

Spring 有一整套的事务管理机制,开发人员在使用的时候不用了解在在底层是怎么实现的。可以使用这样的事务机制,处理各种情况下的事务处理

PART ONE:注解实现事务

在spring中不同的操作有不同的事务管理器

JDBC事务管理器: DataSourceTransactionManager
Hibernate 对应的事务管理器:HIbernateTransactionManager
...

一:完成相关的XML配置

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--启用事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager" />

二:使用事务注解 @Transactional

//在Service 层的方法上添加注解@Trasactional,就可以实现事务管理
@Transactional
public void Test(){...}

PART TWO

一:事务的传播行为

当一个事务方法中调用另一个事务时,必须指定事务该如何传播;在注解@Transactional 的属性中 propagation 进行指定

/*例如,买书作为一个功能,要完成的数据库操作是:书本的数量-1,自己的钱减少。这是一个事务方法*/
@Transactional
public void buyBook(){...}
/* 现在一个人要买两本书,这也是一个事务方法,并且这个方法中要调用buyBook*/
@Transactional
public void buyBooks(){
	buyBook();
	buyBook();	
}
/**
* 现在一本书10 但是只有15 块钱,执行的结果会是一本书都没有买到
* 原因: Transaction 的默认传播属性 propagation=Propagation.REQUIRED 
  1. Transactional的默认传播属性 propagation=Propagation.REQUIRED
    表示:使用调用方法的事务(也可以看成:忽视了被调用方法的事务声明)

  2. Transactional的传播属性 propagation=Propagation.REQUIRES_NEW
    表示:该方法必须开启一个新的事务,并在自己的事务中运行,如果当前被调用事务正在运行,那么调用方法的事务要挂起

@Transactional(propagation =Propagation.REQUIRES_NEW)
public void buyBooks(){
	buyBook();
	buyBook();	
}
/* 现在一本书10 但是只有15 块钱,执行的结果会是买到了一本书,第二本书没有买到
*buyBooks 事务开始,buybook 事务开始,buyBooks 事务挂起;buyBook 事务结束,buyBooks 事务继续,buyBook 事务开始,因为钱不够,buyBook 事务回滚,回滚到当前的buyBook 事务开始的地方,buyBook 事务结束,buyBooks 事务开始
* 知道buyBooks 运行结束 buyBooks 事务结束
* buyBooks 本身时有事务的,因为事务传播属性propagation = Propagation.REQUIRES_NEW 会在buyBooks 事务中新开一个事务buyBook 并且在buyBooks 事务中运行
*/

二:事务的隔离级别

并发事务所导致的问题,当一个或多个应用程序中的多个事务在同一个数据集上并发执行时,可能会发生许多的意外问题(脏读,不可重复读,幻读)
使用@Transactional 的属性 isolation 指定提交级别 isolation=Isolation.RED_COMMITTED 读已提交

三: 事务的回滚属性

Spring 默认情况下对所有的运行时异常进行回滚,也可以通过属性的是设置,指定对那些异常进行回滚,对那些异常不进行回滚

/*涉及的属性*/
对那些异常进行回滚 rollbackFor={异常.class} rollbackForClassName
noRollbackFor  noRollbackForClassName
/*一般不会对这个属性进行设置,使用默认的出现运行时异常就进行回滚*/

四:使用readyOnly

设置 readOnly 属性 readOnly = true 表示这个事务只读取数据不糊更新数据,这样可以帮助数据库引擎优化事务;当这个事务确实为一个只读属性的时候就要进行这样的设置

五: 事务过期

设置 timeout 属性,timeout= 秒数,事务的执行之间超过Timeout 的设置时间,就会被强制回滚(尽管没有异常)

在买书的buyBook 事务中添加代码,进行测试
@Transactional(timeout=2)
public void buyBook(){
try{
	Thread.sleep(4000)
	}catch(Exception ex){...}
/*此时你买一本书,你还有15块钱,你也无法购买成功,因为,设置的最长时间是2s 但是函数中设置了睡眠时间4s 事务的存在时间超过了2s 就会被强制回滚*/
/* 好处在于: 在这种情况下 减少事务的占用时间*/

PART THREE : 使用XML配置文件的方式配置事务

首先配置需要的bean
配置事务管理器

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

配置事务属性

<!--1.配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--2.配置事务属性-->
    <tx:advice transaction-manager="transactionManager" id="txAdvice">
        <tx:attributes>
            <tx:method name="TestTwo" propagation="REQUIRES_NEW" />
            <tx:method name="方法名"   相应的属性配置 />
            <!--get* 表示所有的getxxx() 方法-->
             <tx:method name="get*"   readOnly="true" />
            <!--这里可以在那些方法上进行配置属性,完全看事务的切入点;如果事务的切入点是一个方法,那么这里肯定就只能对哪一个那一个方法进行属性配置-->
        </tx:attributes>
    </tx:advice>

<!--3.配置事务切点,以及把事务切入点和事务属性关联起来-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* spring.AOP.Test.jdbcTemplateTest.TestTwo(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值