@Transactional 关于方面的建议可能吗?
我可以将 @Transactional 标签应用于方面建议吗?我正在尝试使用方面将对服务层(com.mycompany.app.myapp.service.*)的所有调用包装在事务中。我的方面是正确拦截对服务层的调用,但我不知道如何启动事务。我认为我可以应用 @Transactional 标签,因为我已经有了该标签,所以它会选择它并开始交易。我缺少什么?
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();
}
}
Can I apply the @Transactional tag to an aspect advice? I'm trying to wrap all calls to the service layer (com.mycompany.app.myapp.service.*) in a transaction using aspects. My aspect is properly intercepting the calls to the service layer, but I can't figure out how to start a transaction. I thought I could apply the @Transactional tag and because I've got the tag, it'd pick it up and begin the transaction. What am I missing?
XML configuration:
<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>
Aspect w/pointcuts:
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() {};
}
The advice I'm trying to apply to my pointcuts:
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
下面我有一个示例,展示如何将
@Transactional
与inServiceLayer()
Pointcut
一起使用。我选择将正常流程与异常流程分开。这就是为什么我不使用@Around
建议。快速浏览一下您的代码后,我不得不问为什么您用
@Transactional
注释您的Pointcut
?您应该只标记您想要在事务中执行的业务方法。我希望这有帮助!
Below I have an example that shows how you can use
@Transactional
together with yourinServiceLayer()
Pointcut
. I have chosen to separate the normal flow from the exception flow. That is why I do not use the@Around
advice.After a quick look on your code I have to ask why you have annotated your
Pointcut
with@Transactional
? You should only mark your business methods that you want to be executed in a transaction with that.I hope this helps!
正如@Espen所说,您应该直接在业务方法上应用
@Transactional
,因为注释本身会导致Spring创建一个将事务应用于您的方法的方面。所以不需要手动创建aspect。但是,如果您想将事务应用于所有服务方法以及通过这些切入点选择的任何其他内容,您应该使用 xml 配置来创建事务。 在文档中查找声明式事务管理
另外,我认为您不能将
@Transactional
应用于建议。至少它对我不起作用。As @Espen said you should apply
@Transactional
on your business methods directly as the Annotation itself causes Spring to create an Aspect that applies transactions to your method. So there is no need to create an aspect manually.However, if you want to apply transactions to all you service methods and whatever else you selected with those pointcuts you should do use the xml configuration to create the transactions. Look for declarative transaction management in the documentation
Also I don't think you can apply
@Transactional
to an Advice. At least it is not working for me.Spring事务注解在运行时创建一个代理对象。因此,如果您在向服务提供建议的建议上应用事务注释,则事务将针对建议而不是服务,因为建议适用于服务的代理对象,而您的事务注释将适用于服务的代理对象。建议而不是建议的主要方法。理想情况下,您的建议不应是服务功能的扩展。这违背了代理模式的目的。
Spring transaction annotation at run time creates a proxy object. So if you apply transactional annotation on an advice which is advicing the service then the transaction will be for the advice and not for the service since the advice works on a proxy object of the service and your transactional annotation would work on a proxy object of the advice and not the main method of the advice. Ideally you should not be having an advice which is an extension of the functionality of the service. This defeats the purpose of the proxy pattern.
robgmills
您可以使用上面的周围建议,但需要做一些小的更改。
(propagation = Propagation.REQUIRES_NEW)
添加到@Transactional
在上面。
@Transactional
注释添加到已添加切入点inServiceLayer()
的服务方法。robgmills
You can use above Around advice but need to do couple of small changes.
(propagation = Propagation.REQUIRES_NEW)
to@Transactional
in above.
@Transactional
annotation to the service method for which you have added the pointcutinServiceLayer()
.