Spring AOP声明式事务
Spring AOP声明式事务可以帮我们自动管理事务,在业务操作前后加入事务开始和提交,根据约定的命名规则,进行处理。哪些使用事务,哪些不使用事务,使我们专注于业务处理,提高我们开发效率。它是代理模式的设计思想。
使用aop编程,事务管理器真正在做事务做处理,用拦截器进行前后拦截执行事务,拦截哪些地方规则由连接点定义,切点是真正执行事务管理器的地方,通知是定义这整个的事务管理。
传统spring配置
<!-- 配置事务管理器 -->
<bean name="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 注解方式配置事务 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
<!-- 拦截器方式配置事务 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 以如下关键字开头的方法使用事务 -->
<tx:method name="add*" />
<tx:method name="save*" />
<tx:method name="update*" />
<tx:method name="modify*" />
<tx:method name="edit*" />
<tx:method name="delete*" />
<tx:method name="remove*" />
<tx:method name="repair" />
<tx:method name="deleteAndRepair" />
<!-- 以如下关键字开头的方法不使用事务 -->
<tx:method name="get*" propagation="SUPPORTS" />
<tx:method name="find*" propagation="SUPPORTS" />
<tx:method name="load*" propagation="SUPPORTS" />
<tx:method name="search*" propagation="SUPPORTS" />
<tx:method name="datagrid*" propagation="SUPPORTS" />
<!-- 其他方法不使用事务 -->
<tx:method name="*" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>
<!-- 切面,将事务用在哪些对象上 -->
<aop:config>
<!-- 切点 -->
<aop:pointcut id="transactionPointcut"
expression="execution(* edu.gdst.scientific.service.*.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut"
advice-ref="transactionAdvice" />
</aop:config>
SpringBoot配置
Aspect
@Configuration
public class TransactionAdviceConfig {
//连接点
private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.***.service.*.*(..))";
// 事务管理器
@Autowired
private PlatformTransactionManager transactionManager;
// 拦截器配置规则使用 事务(管理器)transactionManager
@Bean
public TransactionInterceptor txAdvice() {
//默认的事务属性,使用事务txAttr_REQUIRED
DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//默认的事务属性,不使用事务txAttr_REQUIRED_READONLY,只读
DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
txAttr_REQUIRED_READONLY.setReadOnly(true);
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
//使用事务
source.addTransactionalMethod("add*", txAttr_REQUIRED);
source.addTransactionalMethod("save*", txAttr_REQUIRED);
source.addTransactionalMethod("delete*", txAttr_REQUIRED);
source.addTransactionalMethod("update*", txAttr_REQUIRED);
source.addTransactionalMethod("exec*", txAttr_REQUIRED);
source.addTransactionalMethod("set*", txAttr_REQUIRED);
//只读不使用事务
source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
//其它只读,不使用事务
source.addTransactionalMethod("*", txAttr_REQUIRED_READONLY);
//根据上面的规则,使用事务管理器
return new TransactionInterceptor(transactionManager, source);
}
//通知,使用上面的拦截器,根据AOP_POINTCUT_EXPRESSION连接点(规则)注入事务代码(事务管理器)
@Bean
public Advisor txAdviceAdvisor() {
//切点
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
//设置规则,即连接点AOP_POINTCUT_EXPRESSION
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
//定义通知,前后开启事务处理
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}