How to Rollback in JetBrains/Exposed?


#1

I have started using Kotlin Exposed. One of the early difficulties I got into was that I can’t seem to be able to do a rollback. eg.

transaction {
val result = doSomething()
if (result == false) {
this.rollback()
}
}

In the above code, doSomething() invokes many DAO.new {… }. I want to commit or rollback based on the overall result. However all the DAOs automatically get inserted into the table and the transaction committed. If the question is not entirely clear I could easily contribute a test case.

PS: I tried this.connection.rollback() also.


#2

Why not use transaction block in your DAOs ?


#3

A real example in Spring Boot:

open fun sendMessage(sender: String, receiver: String, content: Map<String, Any>): Message? {
    return transaction {
        try {
            val message = Chat.slice(Chat.id, Chat.createdAt, Chat.sender, Chat.receiver, Chat.content, Chat.readAt).select {
                Chat.id.eq(Chat.insert {
                    it[Chat.sender] = sender
                    it[Chat.receiver] = receiver
                    it[Chat.content] = js.writeValueAsString(content)
                }[Chat.id]) and Chat.deletedAt.isNull()
            }.limit(1).map {
                Message(id = it[Chat.id], createdAt = it[Chat.createdAt], sender = it[Chat.sender], receiver = it[Chat.receiver], content = it[Chat.content], readAt = it[Chat.readAt])
            }.firstOrNull()

            message?.let { zsetOps.add(sender, receiver, message.id.toDouble()) }
            message
        } catch (e: Exception) {
            rollback()
            throw e
        }
    }
}

#4

Thanks for the replies. Finally manged through explicit control of transactions rather than using transaction blocks, since throwing in exception in order to trigger a rollback wasn’t quite appropriate in our context.


#5

Please try TransactionManager.current().rollback(). You can call it anywhere inside transaction{} block to roll back all uncommited changes.


#6

AFAIK, I had tried it (just like I had tried this.rollback()). But nevertheless go back and check once again.


#7

I just tried it out. Yes, TransactionManager.current().rollback() worked and rolled back all uncommitted changes.

Thanks