Проблема реализации декларативных транзакций - PullRequest
6 голосов
/ 29 июля 2010

Я хочу реализовать управление транзакциями на функциональном уровне.Я хочу что-то вроде этого.

class MyService {

статическая транзакция = false

@ Transactional (readOnly = false, распространение = Propagation.REQUIRES_NEW)

public def saveCountry () {Страна co = новая Страна (имя: 'mycountry') co.save () createState ()

}

@ Транзакционный (readOnly = false, распространение = Propagation.REQUIRES_NEW)

public def createState () {State state = новое состояние (name: 'state') state.save () throw new RuntimeException ()}}

Я хочу, чтобы createState () создавал новую транзакцию, независимую от saveCountry (), так что если метод createState () завершился неудачей,

уже сохраненный объект страны не отменяется.Хотя я дал аннотации, но они не дают желаемого эффекта.Здесь создается одна транзакция, которая отменяется при возникновении исключения. Ни один объект не сохраняется.

Может ли кто-нибудь помочь

1 Ответ

1 голос
/ 31 июля 2010

Я бы не рекомендовал такой подход.Когда вы достигнете метода createState (), Grails будет пытаться использовать любые открытые транзакции перед созданием новой, если ни одна из них не будет доступна.

Вместо этого я бы просто использовал небольшие блоки транзакций, которые окружают только необходимый код grails, вместо попытки объявить методы транзакционными

http://www.grails.org/doc/1.3.x/ref/Domain%20Classes/withTransaction.html

, например, я могу получитьлюбой блок, такой как

State.withTransaction { status -> 
   //all the code in here has an explicit transaction   
}

Эта транзакция либо сбрасывается, либо откатывается в конце блока, и транзакция имеет ссылку на объект Spring TransactionStatus.Это дает вам точный контроль зерна при обработке ошибок.Это позволит вам иметь большие транзакционные блоки, но по-прежнему решать, когда и где завершатся транзакции.

Я бы изменил код на

public def saveCountry() {
    Country.withTransaction { status ->
        Country co = new Country(name:'mycountry')
        co.save()
    }
    createState()
}

public def createState(){
    State.withTransaction { status ->
        State state = new State(name:'state')
        state.save()
        throw new Exception
    }  
}

В этом случае страна будет сохранена, но странатранзакция будет отменена

...