1、声明式事务
spring中的声明式事务是通过aop来实现的
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知:-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<!--配置事务的传播特性:propagation 默认REQUIRED 表示支持当前事务,如果当前没有事务就新建一个事务-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPoinCut" expression="execution(* com.bjpowernode.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoinCut"/>
</aop:config>
为什么需要事务?
如果不配置事务,可能存在数据提交不一致的情况
如果我们不在Spring中去配置声明式事务,我们就需要在代码中手动配置事务!
Spring框架中提供的事务处理方案
1、适合中小型项目使用的注解方案
spring框架自己用aop实现给业务方法增加事务的功能,使用@Transactional注解增加事务
@Transactional注解是spring框架自己注解,放在public方法的上面,表示当前方法具有事务
可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等
使用@Transactional的步骤
1.需要声明事务管理器对象
<bean id="xx" class="DataSourceTransactionManager"/>
2.开启事务注解驱动,告诉Spring框架,我要使用注解的方式管理事务
spring使用aop机制,创建@transactional所在的类代理对象,给方法加入事务的功能
spring给业务方法加入事务:
在你的业务方法执行之前先开启事务,在业务方法之后提交或回滚事务,使用aop 的环绕通知
@Around("你要增加的事务功能的业务方法名称")
Object myAround(){
开启事务,spring给你开启
try{ buy(1001,10) spring事务管理器.commit();} catch(Exception e){spring事务管理器.rollback()}
}
使用spring事务处理
<bean id="trasactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
连接数据库,指定数据源
<property name="dataSource" ref="dataSource"/>
</bean>
开启事务注解驱动 告诉spring使用注解管理事务,创建代理对象
transaction-manager:事务管理器对象的id
<tx:annotation-driven transaction-manager="trasactionManager"/>
3.在方法上面加入@Transactional注解就可以了
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,readOnly = false,rollbackFor = {NullPointerException.class,NotEnoughException.class})
rollbackFor:表示发生指定的异常一定会回滚
处理逻辑:
1.spring框架会首先检查方法抛出的异常是不是在rollbackFor的属性值中
如果异常在rollbackFor列表中,不管是什么异常,一定回滚
2.如果你抛出的异常不在rollbackFor列表中,spring会判断异常是不是RuntimeException
如果是,一定回滚
2、使用AspectJ的AOP配置事务管理
适合大型项目,有很多的类、方法需要大量的配置事务,使用aspect框架功能,在spring配置文件中声明类,
方法需要的事务。这种方式业务方法和事务配置完全分离
实现步骤:都是在xml配置文件中实现
1.加入aspectj依赖
2.声明事务管理器对象
3.声明方法需要的事务类型(配置方法的事务属性【隔离级别、传播行为、超时】)
4.配置aop:指定哪些类要创建代理
<!--声明式事务处理:和源代码完全分离的-->
<!--声明式事务管理器对象-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--声明业务方法它的事务属性(隔离级别、传播行为、超时时间)
id:自定义名称,表示标签之内的配置内容
transaction-manager:事务管理器对象的id-->
<tx:advice id="myAdvice" transaction-manager="trasactionManager">
<!--tx:attributes:配置事务属性-->
<tx:attributes>
<!--<tx:method:给具体的方法配置事务属性,method可以有多个
name:方法名称,1)完整的方法名称,不带有包和类名。2)方法可以使用通配符,*表示任意字符
-->
<tx:method name="buy" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置aop-->
<aop:config>
<!--配置切入点表达式:指定那些包中类要使用事务
id:切入点表达式,指定那些类要使用事务,aspectj会创建代理对象-->
<aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))"/>
<!--配置增强器:管理advice和poincut
advice-ref:通知,上面tx:advice的配置
pointcut-ref:切入点表达式的id
-->
<aop:advisor advice-ref="myAdvice" pointcut-ref="servicePt"/>
</aop:config>