spring事务管理传播。需要\u NEW不工作

spring事务管理传播。需要\u NEW不工作,spring,transactions,required,propagation,requires,Spring,Transactions,Required,Propagation,Requires,我的服务班 @Service @Transactional(value = "transactionManager", readOnly = true, propagation = Propagation.REQUIRED) public class DeviceServiceImpl{ @Transactional(readOnly = false) public void blockAllDevices(){ createSmsDeviceBlock(); } public

我的服务班

@Service
@Transactional(value = "transactionManager", readOnly = true, propagation = Propagation.REQUIRED)
public class DeviceServiceImpl{

@Transactional(readOnly = false)
public void blockAllDevices(){

    createSmsDeviceBlock();

}


public void createSmsDeviceBlock(){

    addToLogTables();

    smsService.sendSms();
}


@Transactional(readOnly = false,propagation = Propagation.REQUIRES_NEW)
public void addToLogTables(){
         try {
          //save object with DAO methods...
        } catch (Exception e) {
          throw new ServiceException(ServiceException.PROCESSING_FAILED, e.getMessage(), e);
        }
}
}

从我的控制器调用服务方法blockAllDevices()。 addToLogTables()方法被标记为Propergation.REQUIRED\u NEW,但问题在于addToLogTables()方法未创建新事务,而现有事务正在使用

我想做的事情是,addToLogTables()方法上的事务应该在执行SMSSService.sendSms()方法之前提交


我这里的问题是,如果事务未能提交,在addToLogTables()方法上,它不应该执行smsService.sendSms()方法。

这不是
传播。需要新的
问题。这是一个关于代理如何工作的问题

当Spring代理用
@Transactional
注释的bean时,它基本上将其包装在代理对象中,并在打开事务后委托给它。当委托调用返回时,代理提交或回滚事务

例如,您的bean是

@Autowired
private DeviceServiceImpl deviceService;
Spring实际上将注入一个包装器代理

所以当你这么做的时候

deviceService.blockAllDevices();
您正在调用具有事务行为的代理上的方法。但是,在
blockAllDevices()
中,您正在执行以下操作

createSmsDeviceBlock();
实际上是

this.createSmsDeviceBlock();
其中,
指的是实际对象,而不是代理,因此不存在事务行为

这一点在下文中作了进一步解释


您必须重新设计。

我可以理解,但有没有其他方法可以做到这一点。。。?这就是在同一个bean中创建新事务。您必须从外部或redactor进行调用,以便事务方法位于注入到该bean中的其他bean上。您可以使用基于AspectJ的事务管理和加载时或编译时编织以及spring方面,这允许您进行事务性自调用,私有事务方法等。有关更多信息,请查看Spring文档。