Spring托管事务不会提交一些语句

时间:2014-03-13 14:31:34

标签: java spring transactions spring-transactions

原则上我或多或少有以下代码

@Component
public class SomeService {
  @Autowired
  private SettingsService settingsService;

  @Autowired
  private OtherService otherService;

  @Transactional
  public void storeData(Data d) {
    settingsService.set("setting1", d.getSetting1());
    settingsService.set("setting2", d.getSetting2());
    settingsService.set("setting3", d.getSetting3()); // no effect

    // do something with otherService
  }

  @Transactional
  public void storeData2(Data d) {
    settingsService.set("setting1", d.getSetting1());
    settingsService.set("setting3", d.getSetting3());
    settingsService.set("setting2", d.getSetting2()); // no effect

    // do something with otherService
  }

  @Transactional
  public void storeData3(Data d) {
    settingsService.set("setting1", d.getSetting1());
    settingsService.set("setting2", d.getSetting2()); // no effect
    // settingsService.set("setting3", d.getSetting3());

    // do something with otherService
  }

  @Transactional
  public void storeData4(Data d) {
    settingsService.set("setting1", d.getSetting1());
    settingsService.set("setting2", d.getSetting2());
    settingsService.set("setting3", d.getSetting3());
    settingsService.set("setting3", "doesn't matter"); // works but hacky

    // do something with otherService
  }

  // @Transactional
  public void storeData5(Data d) {
    settingsService.set("setting1", d.getSetting1());
    settingsService.set("setting2", d.getSetting2());
    settingsService.set("setting3", d.getSetting3()); // works but no TX :(

    // calls to otherService go boom because there is no TX
  }
}

通过简单的@EnableTransactionManagement在主配置中启用事务管理。

SettingsServiceOtherService都将某些内容存储在同一个关系数据库中。

现在,当我调用某些storeData方法时,始终对settingsService的最后一次调用没有任何影响,即更改不会在数据库中保留(请参阅{{1} },storeDatastoreData2)。如果我执行最后一行两次(或尝试保留一些虚假数据),一切正常,但这显然是一个黑客(storeData3)。

奇怪的是,在所有情况下,对storeData4的调用都会按原样保留所有内容。

OtherService SettingService方法可以使用set进行注释;描述的错误行为不会改变。只有当我从@Transactional @Transactional方法中移除SomeService时,对storeData的所有调用都会产生效果(settingsService)。但是我真的想要那个交易(我需要它来处理storeData5)。

因此,上述行为表明服务调用原则上有效,但并非所有调用同时进行。我调试了所有内容,所有变量都设置为正确的值。我不知道这种行为的原因是什么,以及如何进一步调试它。

1 个答案:

答案 0 :(得分:0)

在我意识到在运行时发现@Transactional注释的范围之前,我有类似的事务丢失(尽管不完全相同)。

我将简短地讲述一个问题:向您的主叫客户推广@Transactional注释。这可以防止在我们的测试环境中发生的多次交易导致随机混乱。

因此,在您的情况下,无论是调用您的服务方法,都要向其中添加@Transactional。不保证它会解决您的具体问题,但它确实为我们做了。