我理解在更新对象时使用merge的一个重要好处是用户可以在数据库事务之间花费时间而不保持资源打开,然后只需要在保留更改的对象时再次打开事务。
但是,在传统的Web应用程序中,仍然需要合并吗?例如,用户在对象上更新的所有数据将通过请求表单数据传递。因此,打开连接以获取对象,从实体管理器(缓存)中分离对象,调用分离对象上的更改,然后打开另一个实体管理器只是为了将更改的对象合并回到对象中似乎没用。数据库并关闭交易。
这不像用户在交易开始和结束之间花费了不明的时间。这一切都应该“一举”发生,因为请求参数是在管理事务的函数内调用的。
这种使用合并的优势是什么?
例如,假设我们有一个Dog对象。用户发送更改狗的名称和年龄的请求。此请求通过控制器和服务层进入我的Dog存储库/持久层。在这里,实体管理器建立事务的开始,从数据库中获取Dog对象,将其加载到缓存中,并利用自动脏检查来更改Dog对象的名称和年龄。然后,在Dog对象上调用persist方法后,事务将提交和关闭。
这样做有问题吗?为什么我不这样做,而不是:
创建实体管理器,将Dog对象收集到缓存中,关闭实体管理器。已分离的Dog对象的名称和年龄字段已更改。创建新的实体管理器,并合并更新的Dog对象并关闭事务。对我而言,这似乎更浪费资源,因为我们必须创建两个与数据库的连接。我可以理解,如果没有使用传统的无状态请求/响应Web应用程序,并且客户在事务处理之间有更多的时间来处理。
但是,在无状态请求/响应周期中,一旦发送请求,就会发送请求,并且查询的Dog对象的集合到缓存中的时间与返回到数据库的同一对象之间的时间不会因多长时间而变化。客户/用户需要做出决定。正确?
答案 0 :(得分:1)
最后,它取决于更改集的大小(几乎整个实体,关系与单个字段)以及通过请求/响应处理的数据表示形式如何(json,xml或其他类型的键值)对)。但总的来说,你是完全正确的,只需使用一个事务/连接来更新具有请求值的实体。然而,没有黑色或白色,在某些情况下采用不同的方式可能会有用。
答案 1 :(得分:1)
merge
entity state transition的真正优势在于您在多个Web请求中重用分离的实体。
例如,第一个只读请求加载实体,该实体在事务结束并且持久性上下文关闭后保存在当前HttpSession
中。
use用于决定应用于当前加载的实体的修改,因此在以下触发读写事务的Http请求中,用户可以将更改应用于先前获取的实体。
这种方法有两个好处:
SELECT
查询来加载实体。这就是merge
有用的原因。
用户只需点击“更新”即可。视图上的按钮,该数据将以无状态方式发送。
在这种情况下,您可以以无状态方式来回传递实体版本。第二个事务必须获取实体并应用先前版本以及所有其他更改。
这样,您可以确保您不会丢失更新。如果不使用加载时版本,您可能会面临丢失更新现象的风险。