Spring事务是否通过新实例传播

时间:2014-08-18 07:27:29

标签: spring spring-transactions

我正在研究一堆由我之前的人编写的遗留代码,我对一种特殊的设置感到困惑,并想知道这是否曾经开始使用。

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,我希望这与它有任何关系。

1 个答案:

答案 0 :(得分:2)

我认为代码是正确的,第二个@Transactional应该重用现有的事务。

因为:

1)Spring事务处理由Proxies或AspectJ建议完成。如果由Proxies完成,那么MySiteIdUpdate需要调用注入的实例(这就是你所做的)。如果您使用AspectJ,那么无论如何它都应该可以工作。

2)使用的代码的关联事务是由Thread完成的,这意味着,只要你在启动事务的线程中“是”,就可以使用它。 (你没有开始一个新的线程,所以它应该工作)


另一种解释方法:当你的调用层次结构中有一些不属于spring bean的方法时,它是完全合法的。这不应该使事务处理失败。