设计模式-工作单元(Unit of Work)

发布于:2024-08-13 ⋅ 阅读:(116) ⋅ 点赞:(0)

工组单元

记录在业务事务过程中对数据库有影响的所有变化。
不合实际的方法:

  • 在每次修改对象模型时对数据库进行相应的修改,但会产生大量小规模的数据库交互,降低性能。
  • 采用一个对整个交互过程都开放的事务,尤其是为避免不一致而跟踪读过的对象

运行机制

维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决。

使用工作流单元就是为了处理数据库的变化。为此,工作单元需要知道应该记录哪些对象,可以采用:

  • 调用者注册(caller registration)

如果用户改变了某个对象,就必须将它注册到工作单元上,没有注册的对象提交时不会写入数据库。

  • 对象注册(object registration

调用者不在负责注册,把注册方法置于对象方法中。从数据库中加载的对象会将加载的对象注册为clean,而setting方法会将要设置的对象注册为dirty的。

一般地,工作单元被:放置在一个公共地方;传递给对象;调用(由生成的代码)。

  • 工作单元控制器(unit of work controller

工作单元控制所有数据库的读操作,一旦读对象,注册为clean,并产生一个拷贝,提交时比较发生的变化。

工作单元的其他用途

  • 当数据库使用引用完整性,而且不能仅仅依靠提交时检查完整性时,用来保证更新顺序,如根据外键决定先写哪张表的细表。
  • 较少死锁的可能性
  • 处理批量更新。批量更新(batch update)的思想是把若干SQL命令作为一个单独的单元发送,这样可以在一次单独的远程调用中得到处理。
  • 用于任何事务资源,调整消息队列和事务监控。
     

使用时机

工作单元解决的基本问题是记录操作过的各种对象,以便知道为了使内存中的数据与数据库同步需要考虑哪些对象。
不用工作单元一些思路:

  • 最简单的方法是,在修改任何一个对象时就显式地保存该对象,
  • 问题:和数据库过多的交互。
  • 可以把对数据库的更新操作放到最后,因此需要记录跟踪。
  • 问题:跟踪变量可以和事务脚本一起工作,但和领域模型很难一起使用
  • 把每个被改变的对象加上dirty标志比变量记录要好,价值体现在对dirty的搜索上
  • 问题:跨越一个更一般的对象网络(如领域模型)比较困难。
     

工作单元示例(java

示例展示了一个工作单元,它能跟踪一个业务事务的所有变化,然后在提交变化时将变化写入数据库。

Step1 创建三个对象列表:new领域对象、dirty领域对象、removed领域对象

Step2 用注册方法维护列表状态,如检查ID的空值,保证一个dirty对象没有注册为new对象

Step3 提交方法为每个对象定位数据映射器,并调用适当的映射方法。

Step4 注册对象。此时,每个领域对象都需要找到服务于当前业务事务的工作单元

Step5 给出抽象领域对象的标记方法,注册领域对象到工作单元。

Step6 具体的领域对象在适当的位置标记自己。

Step7 创建工作单元管理代码。