【问题标题】:@Transactional not applied to all controller actions@Transactional 不适用于所有控制器操作
【发布时间】:2017-02-17 08:03:43
【问题描述】:

在从 Grails 3.1.11 更新到 3.2.0 后,我们注意到控制器的一项操作不再起作用:

@Transactional(readOnly = true)
class RoomPlanController {
    ...
    def show(RoomPlan roomPlan) {
        ...
    }
    def getRooms(RoomPlan roomPlan) {
        ...
    }
}

问题是当我们调用roomPlan/getRooms/1roomPlan 为空。如果我们用相同的参数调用show 动作,则roomPlan 设置正确。

在控制器内部调用getErrors() 会得到以下错误消息:

无法获取当前的休眠会话;嵌套异常是 org.hibernate.HibernateException: No Session found for current thread

它起源于 grails.artefact.Controller.initializeCommandObject。经过更多调试后,我注意到 showgetRooms 之间的堆栈跟踪有所不同

show 的堆栈跟踪:

show:100, RoomPlanController (at.byte_code.businessSuite.hotel)
$tt__show:-1, RoomPlanController (at.byte_code.businessSuite.hotel)
doCall:-1, RoomPlanController$_show_closure13 (at.byte_code.businessSuite.hotel)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)

getRooms 的堆栈跟踪:

getRooms:109, RoomPlanController (at.byte_code.businessSuite.hotel)
getRooms:-1, RoomPlanController (at.byte_code.businessSuite.hotel)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)

错误消息和不同的堆栈跟踪让我们假设它与数据库会话/事务有关,并且在将 @Transactional(readOnly = true) 添加到操作之后,一切都按预期工作,并且在更新到 grails 3.2.0 之前。如果我们删除注释并再次失败。

我们无法在任何其他控制器中看到该问题,也无法在小型测试项目中重现该问题。我们已经尝试在一个全新的工作站上重建该项目,而我们并没有。

有其他人观察到这样的问题吗?

【问题讨论】:

  • 也许我在这里遗漏了一些东西(很多人在控制器中进行服务工作)。不应该在服务的上下文中使用事务性吗?不说你提出的问题不是一个有效的问题。纯粹是围绕最佳方法和正确用法
  • 你是对的,但是 Grails 生成的控制器包含注释。我认为这是因为目前没有脚本可以自动生成相应的服务,只有一个空的,所以逻辑一定是最好有正确的事务分界(保存/更新/删除操作有 @Transactional 和其余的将@Transactional(readonly=true)) 放在错误的位置,而不是根本没有。
  • 该操作仅渲染模型的一些数据,因此恕我直言,单独的服务是不必要的和开销。也许我错了,但正如 Burt Beckwith 指出的那样,这是从生成的 grails 控制器中推荐的方式。
  • 我根本不会说它是“建议的”。就是这样。 “建议”和“正确”的方式实际上是使用服务。与整个应用程序相比,拥有和使用服务的开销是如此之小,这是可笑的。

标签: grails transactions spring-transactions grails3


【解决方案1】:

我认为您甚至不需要控制器中的@Transactional(readOnly = true)。

Grails 控制器默认是只读的。您可以简单地从控制器中删除注释。

相比之下,Grails 服务类默认是事务性的。如果需要调用 save() 方法,最好在服务类中调用该方法。

【讨论】:

  • 没有@Transactional,域类的数据绑定不起作用,因为默认情况下控制器不是事务性的。问题是是否有其他人观察到类级别事务注释未应用于所有操作的问题
  • 我认为@Transactional 与域类属性的数据绑定没有任何关系。当我应用类级别事务注释时,它已应用于所有操作。检查您的 UrlMapping 规则以确保适用于 show() 的规则也适用于 getRooms()
  • 好吧,这是未应用类级别注释的实际问题。在 grails 3.1.x 中工作,在 3.2 中失败。至少对于这个控制器。我们无法观察或重现其他控制器中的错误。因为我们无法在测试项目中重现该问题,所以我们无法在 grails 项目中创建问题单,我们在这里询问是否有人观察到相同的问题以找到其根本原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-07
  • 1970-01-01
  • 2018-01-22
相关资源
最近更新 更多