berg369 2009-07-27 15:00 采纳率: 85.7%
浏览 201
已采纳

讨论一下,延迟持久化--这种需求能否实现?

web应用中,第一个请求时不保存到数据库,而保存为一个句柄传递并forword或redirect到另一个表单,第二个表单提交并处理时,调用这个句柄保存到数据库。能不能想出办法实现这种需求呢?

详细说一下这种需求的应用场景:一个组件化的web系统,由容器(控制器并提供其它一些服务)和许多组件组成,其中一个操作是:用户填写容器的一个表单,提交后容器根据某域的值 forward到某个组件的一个表单(但不保存到数据库),用户填写组件表单后提交,第二个表单及处理均是组件中的代码实现的,组件保存第二个表单到数据库,同时需要实现第一个表单数据保存到容器数据库。

组件开发者不应了解容器的细节,因此不能把第一个表单保存在第二个表单的隐藏域中提交后处理,组件开发者甚至不需要了解容器需要的数据库表结构,甚至容器和组件可能属于两个不同的库! 到第二个表单也可能是redirect过去,第二个表单也不会得到前一表单的request对象,但可以得到句柄的ID,将附在redirct请求后传递。

我想这种需求很普遍也很有意义,也不一定是保存数据库了,也可以是延迟做其它的处理工作,但我没有想出实现的办法来,各位高手有没有主意?
问题补充
魔力猫咪:不了解seam,请问其实现这种需求的原理是什么?
kjj:“句柄”只是为了理解的方便,我意思是第一次请求时为操作建立了所有的准备但不立即执行,第二个请求时只调用一下就可以执行了,而且,第二个请求的处理者不需要了解那个操作的细节。
魔力猫咪和miroku都提到了session,但这种方式必须让第二个请求的处理者了解存放在session中的数据结构和需处理的细节,由第二个请求的开发者来做实现,但我希望能完全解耦,第二个请求的处理者只需调用,不需要了解细节。也只有这样才能使容器和运行于其中的组件能够分开。

这种需求能实现吗?

问题补充:
非常感谢大家的意见,高手真多啊!

我想用session可以,就是创建一个类的对象实例,把第一个表单的数据设置为该对象的属性,这个类有一个方法会执行保存数据库,把这个对象放在session中,第二个表单保存时取出调用保存方法就行了。是这样吧?

pocketduck :保存完成后从session中删除这个对象,即使不删除也没关系吧,怎么会出现内存泄漏呢?有必要另外做缓存吗?

sjynt131:查了一下享元类,没看明白它怎么解决我的问题呢?

kjj:谢谢!又了解了RIFE框架,还真是,它与我正在做的东西很相似呢。

问题补充:
sjynt131兄给的单态例子似乎不是典型的享元,享元是支持大量细粒度对象,感觉这里没有这个需求,而且对于延迟操作没有什么关系。
延迟操作看来还是要靠session,可以在第一个表单的处理类中加一个execute方法,取第一个表单的值为该类的属性赋值,但不执行execute方法,即准备好数据但不立即持久化,然后把这个对象放在session中然后重定向,而第二个表单的处理中取出这个对象并执行execute方法就可以了。第二个表单的处理者不需要了解细节,只需从session中取出指定对象并执行,然后从session中清除。
问题补充:
谢谢sjynt131兄,明白了,的确可以作为共享对象来存取。但我觉得还是用session好一点,为什么要和session解耦呢?
设计session这种基于会话生命周期的对象恐怕也是为了解决这类问题吧,session会自动消失掉,而这个共享类需要手工维护,而且不容易避免key的重名在很多人用的情况下。

  • 写回答

12条回答 默认 最新

  • sjynt131 2009-08-06 10:25
    关注

    如果是你前面的应用场景,那放到Session中和享元效果区别不大,但你后面提过“也可以是延迟做其它的处理工作”,我的理解可能会有其他的应用。
    比如:你所说的第二个请求的执行者如果和第一个执行者不是同一个Session。
    另如:每天晚上定时运行一个服务去处理这些Bean,进行一定逻辑处理后才把符合条件的数据进行处理。这种情况当前Action只要将key放到一个队列中就可以了,定时运行的服务到队列中取Key,再去享元中去Bean。这种例子就不能放到Sessioin中了,Session并不是共享的,而且也会自动消失掉。
    至于“这个共享类需要手工维护”,我认为处理完数据后再从享元中删除数据才比较复合逻辑,当然你也可以把享元做复杂些,比如设置数据的失效时间,将失效的Bean从享元中去除。这个根据需求而定。
    另外Key的生成可以使用类似UUId的产生方式,这样完全可以避免重复。
    实际上我提出用享元解决问题主要是因为你提到“但我希望能完全解耦……也只有这样才能使容器和运行于其中的组件能够分开”,而享元可以比较彻底的提供一个解藕的解决方案而已。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(11条)

报告相同问题?

悬赏问题

  • ¥50 远程桌面打开Mastercam、没有许可证、物理机打开正常
  • ¥15 ubuntu安装gdal后java读取tif文件报错
  • ¥15 请问lammps怎么做两种金属连接的原子浓度分布图
  • ¥15 求jacquard数据集
  • ¥15 w10部分软件不能联网
  • ¥15 关于安装hbase的问题(操作系统-windows)
  • ¥15 novnc连接pve虚拟机报错安全协议不支持262
  • ¥15 设备精度0.03给多少公差能达到CPK1.33
  • ¥15 qt+ffmpeg报错non-existing PPS 0 referenced
  • ¥50 MacOS 使用虚拟机安装k8s