开发者

Transaction when saving many object in Grails service

I am having a problem with transaction in Grails. I want to save a list of object to DB by a checking condition at each object. All these process I want to put to one transaction, it means if the k-th object does not satisfied the checking condition, all previous objects (from the first object to the (k-1)th one) will be rolled back from DB. Here is my example:

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
         }
    }
    // ...
}

As you may see, I set transactional variable to true and I've tried to use flush : true and flush : false, but it didn't work as I want. I've read this article Rolling back a transaction in a Grails Service And the author recommended that the service method should throw a RuntimeException then the process will be rollbacked. But if I want to throw another exception, so what I have to do? Could you please give me some suggestions on this problem? Thank you so much!


You can throw any exception that extends from RuntimeException to rollback the transaction. Or you can use Programmatic Transactions, using withTransation, to have more control over the transaction.


Could you verify that saveManyPeople() is within a Service and not a Controller?

The static transactional = true isn't respected in a Controller. I am suspecting that this is the issue.

If you need to have transactional support with the controller, you could always use DomainClass.withTransaction. Reference Documentation Example:

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()
        }
    }   
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜