我正在研究一堆由我之前的人编写的遗留代码,我对一种特殊的设置感到困惑,并想知道这是否曾经开始使用。
Spring中有一个托管bean,它有一个事务方法。
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Throwable.class)
public boolean updateDraftAndLivePublicationUsingFastDocumentsOfMySite(List<FastDocumentLite> fastDocumentLites, Long mySiteId) throws Exception { ... }
现在在该方法中,我找到了调用更新方法fe的新实例:
boolean firstFeed = new MySiteIdUpdate(publishing, siteDao, siteDomainService).update(siteId, fastDocumentLites.get(0).getMySiteId());
根据我对IOC的理解,这个新类不是由spring管理的,它只是bean中的一个变量。现在进一步了解更新方法,您会看到另一个服务被调用。
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Throwable.class)
public void activateSubdomainForSite(Long siteId, boolean activationOfSite)
因此,如果打开一个事务,它应该传播到此服务中。但是,如果MySiteIdUpdate对象不是由spring管理的,那么我不会得到的是第一个事务向前移动到activateSubdomainForSite方法吗?或者是在这里打开另一个交易。我查看了日志,我相信它是后者,但在我宣布这个遗留代码是项目负责人的完全垃圾之前,我宁愿请专家们进行第二次观察。我在某个地方遇到了StaleStateException,我希望这与它有任何关系。
答案 0 :(得分:2)
我认为代码是正确的,第二个@Transactional
应该重用现有的事务。
因为:
1)Spring事务处理由Proxies或AspectJ建议完成。如果由Proxies完成,那么MySiteIdUpdate
需要调用注入的实例(这就是你所做的)。如果您使用AspectJ,那么无论如何它都应该可以工作。
2)使用的代码的关联事务是由Thread完成的,这意味着,只要你在启动事务的线程中“是”,就可以使用它。 (你没有开始一个新的线程,所以它应该工作)
另一种解释方法:当你的调用层次结构中有一些不属于spring bean的方法时,它是完全合法的。这不应该使事务处理失败。