知识卡片
工作单元记录变化的三种技术
内容
工作单元要发挥作用,首先得知道自己该记录哪些对象的变化,实现这一点主要有三种技术。调用者注册:谁改了对象,谁就必须显式把这个对象注册到工作单元,没注册的对象提交时不会被写入数据库——好处是允许在内存里改动对象却不写库(比如临时对象、测试场景),坏处是容易因为粗心漏注册而引发难以察觉的漏洞,作者本人认为这点灵活性带来的混乱得不偿失,宁愿用显式拷贝达到同样目的。对象注册:调用者不再负责注册,而是把注册逻辑内嵌进对象自己的方法里——从数据库加载时自动注册为”干净”,调用setter时自动注册为”脏”;代价是工作单元必须以某种方式被对象拿到(传参或放进众所周知的会话对象里),且仍然要求开发者记得在每个该触发注册的地方老老实实调用注册代码,一旦遗漏同样是隐蔽漏洞(也可以借助代码生成或面向方面编程自动织入这些调用,从而把数据库相关代码彻底和常规业务代码分离)。工作单元控制器:工作单元本身接管所有数据库读操作,对象一读出来就注册为”干净”并生成一份拷贝,提交时把当前对象和这份拷贝逐一比较来判断到底变没变——这样可以做到只更新真正改变了的字段、且完全不需要在对象内部埋注册调用,代价是提交阶段的比较工作变重;折中方案是只拷贝真正发生变化的对象,需要注册但仍能有选择地更新,读多写少的场景下能大幅减轻拷贝负担。
结构图:
flowchart TB
A["工作单元记录变化的方式"]
A --> B["调用者注册<br/>改了就手动登记<br/>易漏注册但灵活"]
A --> C["对象注册<br/>setter/加载时自动登记<br/>仍需开发者不忘埋点"]
A --> D["工作单元控制器<br/>读时留拷贝,提交时比对<br/>免埋点但比较开销大"]
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第11章 对象-关系行为模式"之"11.1 工作单元"(源文件:_epub-src/OEBPS/Text/000092.html)
- 结论依据:原文说明"用调用者注册的方式,用户如果改变了某个对象就必须将它注册到工作单元……用对象注册的方式,调用者就不再负责注册……从数据库加载对象会将加载的对象注册为'干净'的;setting方法会将要设置的对象注册为'脏'的……另一种技术是工作单元控制器……一旦对象被读取,就将它注册为'干净'的对象……工作单元在读操作的时候将产生一个拷贝,在提交时比较当前对象和拷贝对象,看对象是否发生了变化",直接支撑本卡结构图。
- 原始内容:一个折中的方法是只拷贝改变了的对象。这需要注册,但是它支持有选择的更新,因此当读操作大大超过写操作时,它还会极大地降低拷贝操作的负担。