我有一个grails(2.5.2)应用程序,带有mysql和NoSQL交互。有一种主要/主要服务方法可以调用另外两种方法:
class mainService {
static transactional = false
NoSQLDataAccessService noSQLDataAccessService
// main/principal method
@Transactional
void save(json){
// (1) creating domain entities from json
addNewDomainEntities(entities)
// (2)
noSQLDataAccessService.set(json)
}
@Transactional
void addNewDomainEntities(entities){
// save the entities in a mysql schema and use save(flush:true)
// because i need the generated id's
}
}
如您所见,此mainService创建新的域实体(1),刷新会话以获取ID。然后,我调用其他服务方法(2)将json存储在NoSQL模式中:
class NoSQLDataAccessService(){
static transactional = false
void set(json){
try{
// save the json in a NoSQL schema
} catch(Exception ex){
// if fails, i log the exception and throws it again
throws ex
}
}
}
但是,有时noSQLDataAccessService.set()因外部原因而失败,之前创建的实体仍然存在于mysql数据库中。(这是问题)
包含所有此程序执行的save方法标记为@Transactional,因此如果noSQLDataAccessService.set()抛出异常,则应该不应用所有更改,因为回滚。我没错?
答案 0 :(得分:1)
您可能必须抛出RuntimeException而不是Exception,以按this StackOverflow conversation强制执行回滚。而不是:
throws ex
你可以试试:
throw new RuntimeException(ex)
此外,我建议您明确说明您的事务隔离。也许是这样的事情:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)