我可以将@Transactional标记应用于方面建议吗?我正在尝试使用方面将对服务层(com.mycompany.app.myapp.service.*)的所有调用包装在一个事务中。我的方面是正确地拦截对服务层的调用,但我不知道如何启动事务。我想我可以应用@ transaction标记,因为我已经获得了标记,所以它会拿起它并开始事务。我遗漏了什么?
XML配置:
<bean id="systemArchitectureAspect" class="com.mycompany.app.myapp.aspect.SystemArchitecture"/>
<bean id="transactionAspect" class="com.mycompany.app.myapp.aspect.MyAspect"/>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="AtomikosUserTransaction"
class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="10" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>带有切入点的方面:
package com.mycompany.app.myapp.aspect;
@Aspect
public class SystemArchitecture {
@Pointcut( "execution(* com.mycompany.app.myapp.service..*.*(..))" )
public void inServiceLayer() {};
@Pointcut( "execution(* com.mycompany.data..*.*(..))" )
public void inDataAccessLayer() {};
}我想把这个建议应用到我的切入点上:
package com.mycompany.app.myapp.aspect;
@Aspect
public class TransactionAspect {
@Transactional
@Around( "com.mycompany.app.myapp.aspect.SystemArchitecture.inServiceLayer()" )
public Object interceptServiceLayer( ProceedingJoinPoint pjp ) throws Throwable
{
return pjp.proceed();
}
}发布于 2011-04-08 22:28:32
下面我有一个例子,展示了如何将@Transactional与inServiceLayer() Pointcut一起使用。我选择将正常流与异常流分开。这就是我不使用@Around建议的原因。
@Aspect
public class TransactionAspect {
private TransactionService transactionService = new TransactionServiceNull();
@Pointcut( "execution(* com.mycompany.app.myapp.service..*.*(..))" )
public void inServiceLayer() {};
@Pointcut("execution(@org.springframework.transaction.annotation
.Transactional * *(..))")
public void transactionalMethod() {}
@Before("transactionalMethod() && inServiceLayer()")
public void beforeTransactionalMethod(JoinPoint joinPoint) {
transactionService.beginTransaction();
}
@AfterReturning("transactionalMethod() && inServiceLayer()")
public void afterTransactionalMethod(JoinPoint joinPoint) {
transactionService.commit();
}
@AfterThrowing(pointcut = "transactionalMethod() && inServiceLayer()",
throwing = "e")
public void afterThrowingFromTransactionalMethod(JoinPoint joinPoint,
RuntimeException e) {
transactionService.rollback();
}
public void setTransactionService(
final TransactionService transactionService) {
this.transactionService = transactionService;
}
}快速浏览一下您的代码后,我不得不问您为什么要用@Transactional注释您的Pointcut?您应该只标记您希望在事务中执行的业务方法。
我希望这能帮到你!
发布于 2011-04-12 20:25:20
正如@Espen所说,您应该将@Transactional直接应用于您的业务方法,因为注释本身会导致Spring创建一个将事务应用于您的方法的方面。因此,不需要手动创建方面。
但是,如果您希望将事务应用于所有服务方法以及使用这些切入点选择的任何其他内容,则应该使用xml配置来创建事务。Look for declarative transaction management in the documentation
另外,我不认为你可以将@Transactional应用于一个建议。至少它对我不起作用。
发布于 2016-06-14 21:09:31
Spring transaction annotation在运行时创建一个代理对象。因此,如果您在建议服务的通知上应用事务注释,那么事务将用于通知而不是服务,因为通知在服务的代理对象上工作,而事务注释将在通知的代理对象上工作,而不是在通知的主方法上工作。理想情况下,您不应该拥有作为服务功能扩展的建议。这违背了代理模式的目的。
https://stackoverflow.com/questions/5588313
复制相似问题