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模式 - freezesoul - freezesoul的博客关于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. 同步到数据库中


  Unit Of Work模式 - freezesoul - freezesoul的博客

我们先来看看如何记录操作过的各种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模式的文章,你可以在这里查看这些文章。。。

如何在NHibernate中使用UnitOfWork(一)

如何在NHibernate中使用UnitOfWork(二)

如何在NHibernate中使用UnitOfWork(三)

Repository 设计模式介绍

为了能够让我们的精力更好的关注与系统的设计,IoC工具必不可少。。所以,这边文章我就结合AutoFac,Asp.net Mvc以及NHibernate来个简单的例子。

首先我们创建一个Asp.net Mvc的项目(mvc2)。

先把我们之前创建好的UnitOfWork和Repository的项目添加进来。

  Unit Of Work模式 - freezesoul - freezesoul的博客

接下来是在Mvc项目中添加一个ProductController。

添加NHIbernate配置文件:

  Unit Of Work模式 - freezesoul - freezesoul的博客

有了配置文件,我们就可以创建我们的install View了。

  Unit Of Work模式 - freezesoul - freezesoul的博客

首先通过Schema创建好对应的数据库中的表,然后再数据库中插入几条数据。。。。。

对应的View:

  Unit Of Work模式 - freezesoul - freezesoul的博客

可以运行下install:

  Unit Of Work模式 - freezesoul - freezesoul的博客

  

上面是使用UnitOfWork模式来插入记录的。

下面我们结合Repository来新增一条product的记录。

首先是Controller部分的代码:

  Unit Of Work模式 - freezesoul - freezesoul的博客

View部分代码:

  Unit Of Work模式 - freezesoul - freezesoul的博客

新增一条记录,试试,

  Unit Of Work模式 - freezesoul - freezesoul的博客

设置个断点:

  Unit Of Work模式 - freezesoul - freezesoul的博客

除此之外,可以使用UnitoOfWork的Session来查询Product或者用Repository来查询prodct;

  Unit Of Work模式 - freezesoul - freezesoul的博客

下面文章里我将结合AutoFac来以及Repository的优化,来让代码更加简洁,实现IoC。

posted @ 2011-12-20 22:22  AriLee  Views(3396)  Comments(0)    收藏  举报