多线程 – Grails 2.5:复杂的“findOrCreate”和线程之间的同步(HTTP会话)

在Grails应用程序中,我们有一个接口,它接受一个类似路径的3级结构,可以从单个请求中的参数创建

level1/level2/document

对象级别2引用级别1和文档引用级别2.

可以并行上载使用相同level1 / level2子路径的多个对象,因此需要实现会话之间的同步.每个帐户都可以有自己的结构.

本质上,逻辑就像一个高级的findOrCreate,必须在多个并发请求之间进行同步.

我的想法是在服务方法中实现这样的东西:

Doc d
synchronised(currentUser) {
    Dir.withNewTransaction {
       Dir l1 = findFirstLevel(level1) // (A)
       if (!l1) {
           l1 = new Dir(name: level1)
           l1.save()
       }
       Dir l2 = findSecondLevel(l1, level2)
       if (!l2) {
           l2 = new Dir(name: level2, parent: l1)
           l2.save()
       }
       d = new Doc(name: docName, parent: l2)
       d.save()
    } // (B)
} // (C)
saveDocumentContent(d, content)

我使用withNewTransaction来确保在同步部分结束之前保存记录,以确保仅为并行上载正确创建相同的结构一次.

但是,在线程T1中运行的服务功能完成之前,数据不会持久存在.这导致由(A)标记的查询在线程T2中返回null,该块被同步块阻塞并在T1完成执行服务方法之前输入.这导致了这样的结构:

D1/D2/D3
D1/D2/D4

代替

D1/D2/D3
     /D4

我的假设是在(B)结束时withNewTransaction数据将被持久化然后并行会话,在T2中运行将使用查询获取数据.

然而,这不会发生.

我错过了什么?

编辑:在开始时清除会话并在同步部分结束时刷新无效.

编辑2:Hibernate 3.6与Grails一起使用.这可能是问题的根源吗?

最佳答案
问题是在同步块之外修改了查询中使用的其中一个属性.其他逻辑正常.

转载注明原文:多线程 – Grails 2.5:复杂的“findOrCreate”和线程之间的同步(HTTP会话) - 代码日志