Spring @Transaction方法通过同一类中的方法调用,不起作用?
我是Spring交易新手。 有些东西我觉得很奇怪,可能我确实理解了这一点。 我想要在方法级别有一个事务处理,并且在同一个类中有一个调用者方法,看起来好像不是这样,它必须从单独的类中调用。 我不明白怎么可能。 如果有人有一个想法如何解决这个问题,我将不胜感激。 我想用同一个类来调用带注释的事务方法。
这里是代码:
public class UserService { @Transactional public boolean addUser(String userName, String password) { try { // call DAO layer and adds to database. } catch (Throwable e) { TransactionAspectSupport.currentTransactionStatus() .setRollbackOnly(); } } public boolean addUsers(List<User> users) { for (User user : users) { addUser(user.getUserName, user.getPassword); } } }
这是Spring AOP的限制。 (dynamic对象和CGLIB)
如果你configurationSpring使用AspectJ来处理事务,你的代码将会工作。
简单的也许是最好的select是重构你的代码。 例如,一个处理用户的类和一个处理每个用户的类。 然后使用Spring AOP进行默认事务处理。
处理与AspectJ交易的configuration提示
要使Spring能够使用AspectJ进行事务处理,必须将模式设置为AspectJ:
<tx:annotation-driven mode="aspectj"/>
如果您使用的Spring版本比3.0版本旧,则还必须将其添加到Springconfiguration中:
<bean class="org.springframework.transaction.aspectj .AnnotationTransactionAspect" factory-method="aspectOf"> <property name="transactionManager" ref="transactionManager" /> </bean>
这里的问题是,Spring的AOP代理不会扩展,而是包装你的服务实例来拦截调用。 这样做的结果是,在你的服务实例中对“this”的任何调用都是在该实例上直接调用的,并且不能被包装代理拦截(代理甚至不知道这种调用)。 一个解决scheme已经提到。 另一个漂亮的方法就是简单地让Spring将服务的一个实例注入到服务本身中,然后在注入的实例上调用你的方法,这将是处理事务的代理。 但是请注意,如果你的服务bean不是单例,那么这也可能有不良的副作用:
<bean id="userService" class="your.package.UserService"> <property name="self" ref="userService" /> ... </bean> public class UserService { private UserService self; public void setSelf(UserService self) { this.self = self; } @Transactional public boolean addUser(String userName, String password) { try { // call DAO layer and adds to database. } catch (Throwable e) { TransactionAspectSupport.currentTransactionStatus() .setRollbackOnly(); } } public boolean addUsers(List<User> users) { for (User user : users) { self.addUser(user.getUserName, user.getPassword); } } }
这是我自我调用的解决scheme。
private SBMWSBL self; @Autowired private ApplicationContext applicationContext; @PostConstruct public void postContruct(){ self =applicationContext.getBean(SBMWSBL.class); }
你可以在同一个类里面自动assemblyBeanFactory并做一个
getBean(YourClazz.class)
它会自动代理你的class级,并考虑到你的@Transactional或其他aop注释。