我在Grails中遇到了交易问题。我想通过每个对象的检查条件将对象列表保存到DB。我希望将所有这些过程放到一个事务中,这意味着如果第k个对象不满足检查条件,则所有先前的对象(从第一个对象到第(k-1)个)将从DB回滚。这是我的例子:
static transactional = true
public void saveManyPeople() {
// ...
List<People> peoples = new ArraysList();
for(i = 0, i < n, i++) {
People newPeople = createPeopleFromRawData(); // return a people object in memory
if(<checking-condition>) {
newPeople.save(flush : false)
} else {
throw new MyCustomizedException() // MyCustomizedException has extended from RuntimException
}
}
// ...
}
正如您所看到的,我将事务变量设置为true,并且我尝试使用flush:true和flush:false,但它没有按我的意愿工作。我读过这篇文章Rolling back a transaction in a Grails Service 并且作者建议服务方法应抛出RuntimeException然后该进程将被回滚。但是,如果我想抛出另一个异常,那么我必须做什么? 你能否就这个问题给我一些建议? 非常感谢你!
答案 0 :(得分:0)
您可以抛出从RuntimeException扩展的任何异常以回滚事务。或者,您可以使用Programmatic Transactions使用withTransation来更好地控制交易。
答案 1 :(得分:0)
您是否可以验证saveManyPeople()是否在服务范围内而不是控制器?
控制器中不尊重static transactional = true
。我怀疑这是问题所在。
如果您需要对控制器提供事务支持,则可以始终使用DomainClass.withTransaction。 Reference Documentation 例如:
Account.withTransaction { status ->
def source = Account.get(params.from)
def dest = Account.get(params.to)
def amount = params.amount.toInteger()
if(source.active) {
source.balance -= amount
if(dest.active) {
dest.amount += amount
}
else {
status.setRollbackOnly()
}
}
}