Использовать TransactionalEventListener, чтобы установить флаг при откате? - PullRequest
0 голосов
/ 25 апреля 2019

Итак, у меня есть метод, который загружает некоторые тестовые данные в базу данных.

object FooTestData{
    var fooID = -1L
        internal set
    var barID = -1L
        internal set
}

fun TestDataInserter.fooTestData(){
        fooID = insertNewFooReturningID("foo")
        barID = insertNewFooReturningID("bar")
    }
}

Теперь я хочу убедиться, что он загружается ровно один раз. Это кажется достаточно простым ...

object FooTestData{
    internal var isLoaded = false

    var fooID = -1L
        internal set
    var barID = -1L
        internal set
}

fun TestDataInserter.fooTestData(){
    if(FooTestData.isLoaded) return
    FooTestData.isLoaded = true

    with(FooTestData){
        fooID = insertNewFooReturningID("foo")
        barID = insertNewFooReturningID("bar")
    }
}

НО что если транзакция - если есть транзакция - в которой это происходит, откатывается?

Тогда у нас нет сущностей в базе данных, недопустимых идентификаторов в объекте FooTestData и установленного флага isLoaded, который не позволяет нам когда-либо снова загружать сущности.

Это неприемлемо.

Вот поведение, которое я хотел бы реализовать:

  • если транзакции нет, загрузка не может быть отменена, считается зафиксированной
  • если есть транзакция, которая фиксируется во время загрузки данных, обрабатывать загруженные данные как зафиксированные
  • если есть откат транзакции, сбросьте статус FooTestData, если он не был зафиксирован ранее

Как мне это сделать?

Я пытался

object FooTestData{
    class DataLoadedEvent(source:Any):ApplicationEvent(source)
    private val eventMulticaster = SimpleApplicationEventMulticaster()
    init {
        eventMulticaster.setTaskExecutor(SimpleAsyncTaskExecutor())
    }

    internal var isCommitted = false
    internal var isLoaded = false
        set(value) {
            field = value
            if(value) eventMulticaster.multicastEvent(DataLoadedEvent(this))
        }

    var fooID = -1L
        internal set
    var barID = -1L
        internal set
}

@Configuration
class FooTestDataConfiguration{

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    fun onCommit(event:FooTestData.DataLoadedEvent){
        println("onCommit, $event")
        if(FooTestData.isLoaded) {
            FooTestData.isCommitted = true
        }
    }

    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    fun afterRollback(event:FooTestData.DataLoadedEvent){
        println("afterRollback, $event")
        if(!FooTestData.isCommitted) {
            FooTestData.isLoaded = false
        }
    }
}

fun TestDataInserter.fooTestData(){
    if(FooTestData.isLoaded) return
    FooTestData.isLoaded = true

    /* TODO: figure out how to do this
    if(there_is_no_transaction){
        FooTestData.isCommitted = true
    }
    */

    with(FooTestData){
        fooID = insertNewFoo("foo")
        barID = insertNewFoo("bar")
    }
}

в двух разных транзакциях (которые я откатил), но я, должно быть, что-то неправильно понял, потому что эти TransactionalEventListeners абсолютно ничего не сделали.

Как получить нужную функциональность?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...