Spring事务的配置详解:AOP配置数据库操作的事务


最近在项目中,由于要重写数据操作层的代码,因此数据库操作的事务,也需要重新配置。下面就借着这个机会总结一下Spring配置事务的几种方式。说到Spring的事务,我们需要先明白2个概念:声明式事务和编程式事务。编程式事务管理,由于和程序的耦合性太大,使用的并不广泛,通常项目中使用的是声明式事务管理。而声明式事务管理的实现原理就是AOP。首先我们来简单的把声明式事务和编程式事务做一下对比:

A,从耦合性上来说,编程式事务耦合性较高,声明式事务耦合性较低;

B,从是否轻量级上来说,编程式事务非轻量级,声明式事务管理轻量级;

C,从实现上来说,编程式事务以代码的形式将事务写在java类中,声明式事务以配置文件的形式将事务写在XML文件中;


看一个简单的XML声明式事务配置代码:

    <!-- 声明式事务配置 --> 
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="transactionInterceptor" 
        class="org.springframework.transaction.interceptor.TransactionInterceptor"> 
        <property name="transactionManager" ref="transactionManager" /> 
        <!-- 配置事务属性 key属性确定代理应该给哪个方法增加事务行为 --> 
        <property name="transactionAttributes"> 
            <props> 
                <prop key="insert">PROPAGATION_REQUIRED</prop> 
            </props> 
        </property> 
    </bean>


一,Spring事务的传播属性(Propagation)

1、PROPAGATION_REQUIRED  --支持当前事务,如果当前没有事务,就新建一个事务,一般默认采用此配置

2、PROPAGATION_SUPPORTS  --支持当前事务,如果当前没有事务,就以非事务方式执行。

3、PROPAGATION_MANDATORY  --支持当前事务,如果当前没有事务,就抛出异常。

4,PROPAGATION_REQUIRES_NEW  --新建事务,如果当前存在事务,把当前事务挂起。

5,PROPAGATION_NOT_SUPPORTED  --以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

6,PROPAGATION_NEVER  --以非事务方式执行,如果当前存在事务,则抛出异常。


二,Spring事务的隔离级别

1、ISOLATION_DEFAULT  --使用数据库默认的事务隔离级别

2、ISOLATION_READ_UNCOMMITTED  --这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据

3、ISOLATION_READ_COMMITTED  --保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

4、ISOLATION_REPEATABLE_READ  --这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读

5、ISOLATION_SERIALIZABLE  --这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

理解Spring事务的隔离级别,需要明白以下几个概念:
1,脏读(脏数据): 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
2,不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
3,幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。


三,JDBC事务的隔离级别

1、TRANSACTION_NONE  --不支持事务,实际项目中很少使用

2、TRANSACTION_READ_UNCOMMITTED  --在提交前一个事务可以看到另一个事务的变化。脏读、不可重复的读和幻觉读都是允许的

3、TRANSACTION_READ_COMMITTED  --读取未提交的数据是不允许的。这个级别仍然允许不可重复的读和虚读产生

4、TRANSACTION_REPEATABLE_READ  --事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现

5、TRANSACTION_SERIALIZABLE  --最高的事务级别,它防止脏读、不可重复的读和虚读

在计算机界,永远要记住一个规律:事务保护的级别越高,性能损失就越大。开发者需要在性能与功能之间做出权衡。


四,关系数据库的事务特性(ACID)

1、原子性(Atomic)  --事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于修改,要么全部执行,要么全部不执行

2、一致性(Consistency)  --事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。

3、隔离性(Isolation)  --一个事务的执行不能被其他事务所影响。事务必须是互相隔离的,防止并发读写同一个数据的情况发生

4、持久性(Durable)--一个事务一旦提交,事物的操作便永久性的保存在DB中。即使此时再执行回滚操作也不能撤消所做的更改


五,AOP事务配置

<!-- Spring事务配置示例-applicationCommon-service.xml文件中 -->
<bean id="TransicationTestService" class="com.java.test.charge.service.impl.TransicationTestServiceImpl">
	<property name="TransicationTestDAO" ref="TransicationTestDAO"></property>
</bean>
<aop:config>
	<aop:pointcut id="TransicationTestService1" expression="execution(* com.java.yangcq.charge.service.TransicationTestService.insert*(..))" />
	<aop:pointcut id="TransicationTestService2" expression="execution(* com.java.yangcq.charge.service.TransicationTestService.update*(..))" />
 	<aop:pointcut id="TransicationTestService3" expression="execution(* com.java.yangcq.charge.service.TransicationTestService.delete*(..))" />
    <aop:advisor pointcut-ref="TransicationTestService1" advice-ref="txAdvice"/>
    <aop:advisor pointcut-ref="TransicationTestService2" advice-ref="txAdvice"/>
    <aop:advisor pointcut-ref="TransicationTestService3" advice-ref="txAdvice"/>
</aop:config> 

pointcut:切入点,一组规定,规定一个切面可以植入到哪些类或者方法。例如上面的配置,id=TransicationTestService1的AOP切面,可以植入TransicationTestService这个接口下的所有的insert操作。简单来说,就是给TransicationTestService这个接口下的所有的insert操作配置事务。
advisor:是一种特殊的Adivice,规定了哪个切面,要植入哪个类的哪个方法。例如上面的配置
<aop:advisor pointcut-ref="TransicationTestService1" advice-ref="txAdvice"/>   //规定了切面TransicationTestService1植入txAdvice

<!--
	Transaction advice definition, based on method name patterns.
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
		<tx:method name="*" rollback-for="com.test.core.TestServiceException" />
	</tx:attributes>
</tx:advice>

<bean id="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>



“究天人之际,通古今之变,成一家之言”                            --《史记》


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值