事务管理方式


1.编码方案 不建议使用,它具有侵入性。在原有的业务代码基础上去添加事务管理代码
2. 声明式事务控制,基于AOP对目标进行代理,添加around环绕通知。
这种方案,它不具有侵入性,不需要修改原来的业务代码


基于xml配置声明式事务管理方案


第一步:在applicationContext.xml文件中添加aop与tx的名称空间


<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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


第二步:在applicationContext.xml文件中配置
Spring提供的advice是传统的spring advice
1. 声明事务管理器


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


2.配置通知
Spring为我们提供了一个TransactionInterceptor来完成增强


Spring声明式事务管理_spring


对于这个增强,我们可以使用spring为我们提供的一个标签< tx:advice>来完成操作


<!-- 配置通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
name:必须的,对哪些方法进行事务控制
isolation 可选 设置事务隔离级别 默认是DEFAULT
propagation:可选 设置事务传播 默认值 REQUIRED
timeout 可选 超时时间 默认值-1
read-only 可选 默认值是false 如果不是只读,它可以对insert update delete操作,如果是只读不可以。
rollback-for 可选 可以设置一个异常,如果产生这个异常,触发事务回滚
no-rolback-for 可选 可以设置一个异常,如果产生这个异常,不会触发事务回滚
-->
<tx:method name="account" />

</tx:attributes>
</tx:advice>


3.配置切面
因为使用的是传统的spring的advice,需要使用


<!-- 配置切面 -->
<aop:config>
<aop:pointcut expression="execution(* cn.nwtxxb.service.IAccountService.account(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>


完整的applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 引入外部的properties文件 -->
<context:property-placeholder location="classpath:db.properties" />


<!-- 创建c3p0连接 -->
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>

<!-- service -->
<bean id="accountService" class="cn.nwtxxb.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>

<!-- dao -->
<bean id="accountDao" class="cn.nwtxxb.dao.AccountDAOImpl">
<!-- 当注入dataSource后,底层会自动创建一个JdbcTemplate -->
<property name="dataSource" ref="c3p0DataSource" />
</bean>

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

<!-- 配置通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
name:必须的,对哪些方法进行事务控制
isolation 可选 设置事务隔离级别 默认是DEFAULT
propagation:可选 设置事务传播 默认值 REQUIRED
timeout 可选 超时时间 默认值-1
read-only 可选 默认值是false 如果不是只读,它可以对insert update delete操作,如果是只读不可以。
rollback-for 可选 可以设置一个异常,如果产生这个异常,触发事务回滚
no-rolback-for 可选 可以设置一个异常,如果产生这个异常,不会触发事务回滚
-->
<tx:method name="account" />

</tx:attributes>
</tx:advice>

<!-- 配置切面 -->
<aop:config>
<aop:pointcut expression="execution(* cn.nwtxxb.service.IAccountService.account(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!--开启事务管理注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

基于annotation声明式事务管理方案


可以使用@Transaction来在类或方法上添加声明式事务管理
注意:需要在applicationContext.xml文件中使用


<tx:annotation-driven transaction-manager="transactionManager"/>


相当于开启注解事务控制


Spring声明式事务管理_spring事务管理_02


问题:关于xml方式与annotation方式的优缺点?
从简单上来说,使用注解更方便。
使用配置的方案,可以对事务配置进行集中维护。


Spring声明式事务管理_xml_03