hibernate - Grails:执行两个修改同一个对象的连续事务的最佳方法是什么?

标签 hibernate grails transactions

在我的服务中,有用户保留的资源。
当用户结束使用/保留资源时,将调用结帐“ Controller 方法”。
在这种方法中,理想情况下应该发生 3 件事。他们是:
1. 资源被释放。
2.调用远程支付服务,根据资源使用量向用户收费。
3.在Reservation对象上标注为已付费。

在这 3 个步骤中,第 1 步应始终进行,而第 2 步和第 3 步只能同时进行。

我的问题是如何在代码中理想地处理这个问题?
(这里,reservation objects 对象包含有关资源预留的信息。如果预留的使用已开始但未结束,则它正在预留引用的资源。)
A:我可以/应该在交易之间共享预订对象吗?或者,
B:我应该在每笔交易中单独“获取”预订对象吗?
C:在所有事务之外首先获取预订对象是否有异味?
D:我现在使用 Grails 2.4.4。您的答案会因 Grails 版本而异吗?我应该升级到更新的版本吗?

这是代码中的示例(我只获得一次预订对象)。
(当然,事务可以发生在服务中,但使用 withNewTransaction 方法更容易证明这一点。)。
这是一个好方法,还是应该如何更改下面的代码?

/*Domain class*/
class Reservation {
    Resource resource;
    Date useStarted;
    Date useEnded;
    Boolean charged;
}


class ReservationController {

    def nonTransactionalPaymentService

    def checkout(){
        def reservationId = params.reservationId as Long

        def reservation = Reservation.get(reservationId )
        Reservation.withNewTransaction {
            // reservation = Reservation.get(reservationId ) ??
            reservation.useEnded = new Date()
            reservation.save(failOnError: true)
        }
        Reservation.withNewTransaction {
            // reservation = Reservation.get(reservationId ) ??
            nonTransactionalPaymentService.charge(reservation)
            reservation.charged = true
            reservation.save(failOnError: true) // I'm screwed if this fails
        }
        // rendering code here
    }
 }

我之所以问这个问题是因为我的代码中有两个现象我还没有完全摆脱:
1.奇怪的异常如:“连接已被废弃PooledConnection”。
2. 获取对象时,之前交易的变化是不可见的。

最佳答案

我发现有以下区别:

def reservation = Reservation.get(reservationId )
Reservation.withNewTransaction {
 ..
}
Reservation.withNewTransaction {
..
}


Reservation.withNewTransaction {
   def reservation = Reservation.get(reservationId )
    // reservation = Reservation.get(reservationId ) ??
    reservation.useEnded = new Date()
    reservation.save(failOnError: true)
}
Reservation.withNewTransaction {
   def reservation = Reservation.get(reservationId )
    // reservation = Reservation.get(reservationId ) ??
    nonTransactionalPaymentService.charge(reservation)
    reservation.charged = true
    reservation.save(failOnError: true) // I'm screwed if this fails
}

这意味着当您记忆时 - 在您生效的新事务中重新获取对象,然后获取最新的更改。
.read 之间也有细微的变化.get以及是否在整体服务中禁用事务。看看queuekit插件里面有很多 newTransaction 东西,试图在任何时候挑选出最新的更新。

关于hibernate - Grails:执行两个修改同一个对象的连续事务的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43704307/

相关文章:

java - CriteriaQuery 带 max 的子查询

java - 如何使用 entityManager 在 JPA 中启动事务

mysql - 事件记录 - destroy_all 并在事务中创建

sorting - Grails排序问题

java - Spring:用于只读事务的单独数据源

java - JPA继承问题

java - JPA更新父子

java - Hibernate:通过一个查询删除所有 child

grails - 在Grails中解码base64图像

grails - Grails最常用/有值(value)的单元测试