我可以提交内部withTransaction闭包

时间:2013-07-18 01:58:54

标签: hibernate grails gorm

我可以在withTransaction关闭内部提交吗?我想在我的Quartz工作中做这样的事情:

Author.withTransaction {
    def author = Author.get(1)
    author.staus = 'processing'
    author.save()
    commit // how can i do this?
    // so some work here which takes 1-2 minutes
    author.status = 'completed'
    author.save()
}

我的想法是,我希望有一个状态屏幕,显示当前正在处理的所有Author,所以我想将状态设置为processing并且能够从控制器中看到这种状态。

编辑: 这可以在没有withTransaction的情况下使用,但我必须withTransaction ...请参阅this question

2 个答案:

答案 0 :(得分:2)

为了从不同的未提交事务中读取值,您的数据库隔离级别必须设置为“read uncommitted”,这通常表示您可能做错了。

你有什么理由不能把它分成单独的交易吗?一个用于将记录标记为“正在进行中”,一个用于执行实际工作?

Author.withTransaction {
    def author = Author.get(id)
    author.status = 'processing'
    author.save()
}

Author.withTransaction() {
    def author = Author.get(id)
    // do some work
    author.status = 'completed'
    author.save()
}

答案 1 :(得分:0)

我会尽可能地坚持@codelark的方法,以编程方式处理事务并为回滚添加逻辑。

这是一个共同事件,我也在这个问题上用codelark挖掘理由。这就是我现在所拥有的:

    Author.withSession{session->
        def author = Author.get(blahId)
        try{
            def tx = session.beginTransaction()
            //Update status to processing
            author.status = 'processing'
            tx.commit()

            //Do your 1 - 3 minutes task
        } catch(e){
            //If there is any exception in that task then rollback transaction
            tx?.setRollbackOnly()
        }

        if(!tx.isRollbackOnly()){
            try {
                def tx2 = session.beginTransaction()
                //Update author status to completed
                //Few pain points can also be taken care of here, like checking if the task completed as expected etc..
                author.status = 'completed'
                tx2.commit()
            }
            catch(Exception e) {
                tx2?.setRollbackOnly() //If you want
            }
        }
    }

@Alidad绝对正确地说,提交/刷新发生在withTransaction块的末尾。因此flush: true内的withTransaction无效。