spring事务和aop同时使用
对同一个类即用aop又用事务,需要指定代理顺序,保证事务的代理包裹aop的代理,也就是事务的order大于aop的order,否则事务会失效,也就是不会回滚。
- 使用aop的地方设置order如下:
@Order(1)
@Component
@Aspect
public class AopDaoRunTime {
private static final Logger LOGGER = LoggerFactory.getLogger(AopDaoRunTime.class);
@Around("execution(* com.qunar.lfz.dao.impl.*.*(..))")
public Object printDaoTime(ProceedingJoinPoint point) {
String methodName = point.getSignature().getName();
Object result = null;
try {
long startTime = System.currentTimeMillis();
result = point.proceed();
long endTime = System.currentTimeMillis();
LOGGER.info("{}方法执行时间为{}ms", methodName, endTime - startTime);
} catch (Throwable e) {
LOGGER.error("获得dao执行方法时间出错", e);
return null;
}
return result;
}
}
- 配置spring事务和aop的xml:
<aop:aspectj-autoproxy proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" order="2"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="xxx"/>
</bean>
aop的配置中指定proxy-target-class="true",会使用cglib生成子类做代理,现在的cglib效率比jdk的基于接口的代理效率高很多
需要注意的是如果使用的是代理对象,对属性的读写都要通过get、set方法来做。代理对象的属性都是null,通过get、set方法才能读写被代理对象中的属性
- spring手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();