@Transactional不适用于方法级别

时间:2013-09-03 10:40:13

标签: java spring transactions

我对Spring 3.2.3 @Transactional注释有疑问。 我的服务类看起来像这样:

@Service @Transactional
class InventoryDisclosureBO {

@Autowired InventoryDisclosureDAO inventoryDisclosureDAO;

private static final Logger log = LoggerFactory.getLogger( InventoryDisclosureBO.class);

public void processDisclosureData(InventoryDisclosureStatus data){
  validate(data);
  persist(data);
}

@Transactional(propagation = REQUIRES_NEW)
void persist(InventoryDisclosureStatus data) {
  inventoryDisclosureDAO.setAllInvalid( data.getUnit());
  inventoryDisclosureDAO.insert( data );
}

void validate(InventoryDisclosureStatus data) {
 ...
}
}

如果我调用persist()方法,那么一切都很完美。但是如果我在课堂级别注释掉@Transactional - 事务没有开始。 有人能告诉我为什么Spring只能在甲醇水平上忽略@Transactional吗?

2 个答案:

答案 0 :(得分:5)

您无法从processDisclosureData()调用persist(),因为它属于同一个类,它将绕过Spring为InventoryDisclosureBO创建的事务代理。您应该从其他bean调用它以使@Transactional注释工作。当Spring向其他bean注入InventoryDisclosureBO bean的引用时,它实际上会引入对包含事务逻辑的InventoryDisclosureBOProxy的引用,例如

    class Bean2 {

      @Autowire
      private InventoryDisclosureBO idbo;   <-- Spring will inject a proxy here

      public void persist(InventoryDisclosureStatus data) {
           idbo.persist(data);     <-- now it will work via proxy
      }
...

答案 1 :(得分:3)

这与spring如何生成事务代理有关。

如果您在类级别拥有@Transactional,那么当您调用InventoryDisclosureBO.processDisclosureData()时,实际上您正在调用启动事务的Spring代理,然后调用实际实现。

如果你在persis()中只有@Transaction,那么当你调用InventoryDisclosureBO.processDisclosureData()时,spring不会启动事务,然后它无法检测到你调用了InventoryDisclosureBO.persist()

所以Spring基本上忽略了persist上的注释,因为它无法添加事务代理。

根据经验,@ Transactal注释应该在公共方法上,并且希望在调用层次结构中相当高(否则每个持久化将最终创建一个新事务)

您可能会发现有关此其他问题的更多信息:Method Interceptor on private methods(任何非公开方法的行为方式相同)

相关问题