原则上我或多或少有以下代码
@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
在主配置中启用事务管理。
SettingsService
和OtherService
都将某些内容存储在同一个关系数据库中。
现在,当我调用某些storeData
方法时,始终对settingsService
的最后一次调用没有任何影响,即更改不会在数据库中保留(请参阅{{1} },storeData
和storeData2
)。如果我执行最后一行两次(或尝试保留一些虚假数据),一切正常,但这显然是一个黑客(storeData3
)。
奇怪的是,在所有情况下,对storeData4
的调用都会按原样保留所有内容。
OtherService
SettingService
方法可以使用set
进行注释;描述的错误行为不会改变。只有当我从@Transactional
@Transactional
方法中移除SomeService
时,对storeData
的所有调用都会产生效果(settingsService
)。但是我真的想要那个交易(我需要它来处理storeData5
)。
因此,上述行为表明服务调用原则上有效,但并非所有调用同时进行。我调试了所有内容,所有变量都设置为正确的值。我不知道这种行为的原因是什么,以及如何进一步调试它。
答案 0 :(得分:0)
在我意识到在运行时发现@Transactional
注释的范围之前,我有类似的事务丢失(尽管不完全相同)。
我将简短地讲述一个问题:向您的主叫客户推广@Transactional
注释。这可以防止在我们的测试环境中发生的多次交易导致随机混乱。
因此,在您的情况下,无论是调用您的服务方法,都要向其中添加@Transactional
。不保证它会解决您的具体问题,但它确实为我们做了。