Транзакция при сохранении множества объектов в сервисе Grails - PullRequest
1 голос
/ 04 апреля 2011

У меня проблема с транзакцией в Grails.Я хочу сохранить список объектов в БД путем проверки состояния каждого объекта.Все эти процессы, которые я хочу поместить в одну транзакцию, это означает, что если k-й объект не удовлетворяет условию проверки, все предыдущие объекты (от первого объекта до (k-1) -го) будут откатываться из БД,Вот мой пример:

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, но это не сработало, как я хочу.Я прочитал эту статью Откат транзакции в службе Grails И автор рекомендовал, чтобы метод службы выдавал исключение RuntimeException, тогда процесс будет откатываться.Но если я хочу выбросить еще одно исключение, то что мне делать?Не могли бы вы дать мне несколько советов по этой проблеме?Большое вам спасибо!

Ответы [ 2 ]

0 голосов
/ 04 апреля 2011

Не могли бы вы проверить, что saveManyPeople () находится внутри Сервиса, а не Контроллера?

static transactional = true не соблюдается в контроллере. Я подозреваю, что это проблема.

Если вам нужна поддержка транзакций с контроллером, вы всегда можете использовать DomainClass.withTransaction. Справочная документация Пример:

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 голосов
/ 04 апреля 2011

Вы можете выдать любое исключение, которое выходит из RuntimeException, для отката транзакции. Или вы можете использовать Программные транзакции , используя withTransation, чтобы иметь больше контроля над транзакцией.

...