Unit Of Work模式
Unit Of Work模式
2011-05-27 23:01:42| 分类: Study | 标签: |字号大中小 订阅
关系数据库映射(行为模式之工作单元)
Unit Of Work模式在ASP.NET MVC 的范例项目中经常用到,是比较受欢迎的一个模式。
什么是Unit Of Work模式呢?
“A Unit of Work keep track of everything you do during a business transaction that can affect the database. When you’re done, it figures out everything that need to be done to alter the database as a result of your work.”
Unit of Work负责跟踪所有业务事务过程中数据库的变更。当事务完成之后,它找出需要处理的变更,并更新数据库。
关于Unit of Work 模式的更多信息,可参考如下链接:
http://martinfowler.com/eaaCatalog/unitOfWork.html
[问题域]
正常情况下,如果使用Data Mapper解决了Domain对象和数据库分离的目的,使用时,如果每当一个Domain对象创建、修改或删除时,最简单的方式就是立即对数据库进行更新操作,但是这样会对数据库产生大量的调用动作。如果不这样做,就必须记录下Domain对象的各种修改动作,以保证最后提交时,对数据库进行相应的更新,保持Domain对象和数据库的一致性。
[解决方案]
找一个处所保存Domain对象的各种变化,最后提交时,就知道应该要做什么修改,并最终写入数据库。而这个处所可以称之为工作单元(Unit of work),使用这种方式被命令为工作单元模式(参考[Martin Fowler企业架构模式])。
工作单元模式(Unit of work)
根据以上描述可知,工作单元模式包括两个主要方面:
1. 记录操作过的各种Domain对象
2. 同步到数据库中
我们先来看看如何记录操作过的各种Domain对象。
1.由调用者注册。比如:调用者创建一个Domain对象时,同时通知工作单元,执行了更新操作。
缺点:有程序开发者主动控制,人是最靠不住的。
有点:可以主动决定是否注册,(也就是决定把Domain更改是否写入数据库)
2.由Domain对象注册。比如:Domain对象中的Create方法中比如加入通知工作单元的代码,工作单元可以作为参数传入,或者固定的地方可以获取(如ThreadLocal保存)。
缺点:也是需要由人在各个Domain对象的各种操作中加入固定通知工作单元代码。
优点:当然具有一致性,同时就可以采用AOP的思想统一操作(比如Proxy,Minxin等)
3.工作单元控制器。总的思路是,工作单元控制所有的读操作,读取对象的时候,对它进行注册为Clean的,并产生一个拷贝,提交时,对比一下哪些字段进行了改变,然后再更新。对于不想拷贝的对象则需要主动进行注册。(TOPLink使用此方式)
缺点:不需要拷贝的对象需要主动注册,否则一律拷贝一个。
优点:对Domain对象的改变只进行了有选择的更新。
接下来讨论工作单元同步到数据库的问题:
1.更新顺序
如果数据库允许,只在事务提交时检查引用完整性,而不是每次SQL都检查,则随便怎么用都可以。如果数据库不允许,则在工作单元中则根据元数据(metadata)指定的顺序执行更新数据库的操作。
2.批量更新
如果有一些列的更新,删除或新增操作,则可以在工作单元中,作为一个单条语句发送请求。
[结论]
工作单元最大的好处就是把各种复杂的操作保存在一个固定的地方。这种模式可以应用于所谓有类似需求的地方。
参考资料:
Patterns of Enterprise Application Architecture (author:Martin Fowler)
=============================================
最近写了一系列的UnitOfWork模式和Repository模式的文章,你可以在这里查看这些文章。。。
为了能够让我们的精力更好的关注与系统的设计,IoC工具必不可少。。所以,这边文章我就结合AutoFac,Asp.net Mvc以及NHibernate来个简单的例子。
首先我们创建一个Asp.net Mvc的项目(mvc2)。
先把我们之前创建好的UnitOfWork和Repository的项目添加进来。
接下来是在Mvc项目中添加一个ProductController。
添加NHIbernate配置文件:
有了配置文件,我们就可以创建我们的install View了。
首先通过Schema创建好对应的数据库中的表,然后再数据库中插入几条数据。。。。。
对应的View:
可以运行下install:
上面是使用UnitOfWork模式来插入记录的。
下面我们结合Repository来新增一条product的记录。
首先是Controller部分的代码:
View部分代码:
新增一条记录,试试,
设置个断点:
除此之外,可以使用UnitoOfWork的Session来查询Product或者用Repository来查询prodct;
下面文章里我将结合AutoFac来以及Repository的优化,来让代码更加简洁,实现IoC。











浙公网安备 33010602011771号