业务对象到关系数据库映射的若干模式 (4)

来源:互联网 发布:模具设计和编程哪个好 编辑:程序博客网 时间:2024/05/18 18:46

事务管理器

 

别名:

工作单元

事务对象

 

动机:

保存对象的过程中,允许对象在某些值不能正常保存时,能以某种方式保存是非常重要的,先前存储对象能够被回滚。在病人例子中,你不仅只存储Patient对象的属性,还要存储它包含的变化过的address对象,如果试图保存任何一个病人的地址对象失败了,你想回滚保存该病人信息时所有的写入数据库操作。一个事务管理器提供开始事务、提交事务和回滚事务的支持。

 

问题:

如何向数据库写入一组对象,当任何写入失败时,将没有任何对象写入。

 

特定约束:

?           对象之间通常以某种方式联系起来,如果一个对象没有正常保存,那您就不想保存相关的对象;

?           知道哪些消息是事务,哪些不存在阻抗不匹配;

?           每个向数据库的写入操作都可以设定为一个单一事务;

?           复杂对象能够构造一个复杂的SQL语句,它包含事务处理,可以看作一个工作单元。

 

解决方案:

构建一个和其他事务管理器类似的事务管理器,这个管理器允许开始事务、结束事务、提交事务和回滚事务。事务管理器通常映射到RDBMS事务管理器,如果它提供的话,所有流行数据库都内嵌了事务管理器,最好是使用它们提供的。

为了性能的原因,也许最好缓冲数据,这种情况,事务管理器有提交和回滚缓冲值的功能是非常重要的。如果你映射的数据库不支持事务管理器,那么你有必要在开始事务时保存对象的初始状态,这样当请求回滚时,初始值能够写回数据存储。

 

示例实现:

没有事务管理,你将使用如下形式:

    anObject save.

这将提交每条发送到数据库的SQL语句,如果在保存anObject过程中发生了某种错误,你将在数据库中留下部分anObject,特别当anObject是一个复杂对象时。

当你使用事务管理,基本上你将anObject构建的所有SQL语句包装起来,告诉数据库,要不保存所有,要不什么都不干,这看起来如下所示:

    beginTransaction

    anObject save

    anotherObject save

    endTransaction

这确保在向数据库提交改变前,所有的保存命令都能成功执行。当你的对象是复杂对象,它知道如何保存他的聚合对象,确保将完整的对象写入数据库中。

下面的代码是从PersistentObject摘录,它们展示了实现事务管理的包装结果,代码(self class beginTransaction)告诉数据库开始和停止一个事务,它依赖于你所使用的数据库和你所用的开发语言。你也许需要扩展事务以处理你特殊的实现,同时,如果你保存的数据库(可能只是一个文本文件)不支持事务,你将不得不开发一个完整的事务管理器以支持用户的需要。本例中将所有保存和删除对象操作包装在一个beginTransaction和一个endTransaction之中。类方法进行数据库联接类的调用,这是VisualAge为它支持的数据库提供提交和回滚事务的地方。

 

Protocol for Public Interface PersistentObject (instance)

 

save

    self class beginTransaction.

    self saveAsTransaction.

    self class endTransaction.

delete

    self class beginTransaction.

    self deleteAsTransaction.

    self class endTransaction.

 

Protocol for Public Interface PersistentObject (class)

 

beginTransaction

    self databaseConnection beginUnitOfWorkIfError:

              [self databaseConnection rollbackUnitOfWork]

endTransaction

    self databaseConnection commitUnitOfWork

 

rollbackTransaction

    self databaseConnection rollbackUnitOfWork

 

结论:

?           复杂对象要不完全保存,要不什么都不保存;

?           半个对象不能维护引用一致性;

?           所有其他写入数据库的应用系统不得不使用事务管理器,你也许不得不增加检查,看在你保存时,是否有其他什么人曾修改过数据库;

?           除非数据库中内嵌了事务管理的支持,写一个完整的事务管理器非常困难。

 

相关或交互模式:

?           事务管理器和事务对象[Keller 98-2]非常相似,事务对象通过在外面构建对象封装事务,这些事务对象提供开始、提交和回滚事务操作。

 

已知应用:

?           大多数数据库类应用系统提供类似的功能或时工作单元的定义;

?           Illinois Department of Public Health TOTSNewBorn Screening项目;

?           VisualWorks在他们的ObjectLens中提供事务管理器

?           VisualAge也在ABTDbm*类中提供事务支持;

?           GemStone GemConnect为数据库对象提供事务管理。

 


联接管理器

 

别名:

       当前联接

       数据库会话

 

动机:

只要一个持久对象被读出或是写入数据库,必须建立一个和数据库的联接。一个数据库事务需要的典型信息是数据库名、用户名和用户口令,这些信息可以在每次访问时向用户获取,这将导致失败的用户验证,因为大多用户不会知道数据库名或别名。你也可以在启动时获取用户名和口令,并在以后的代码中使用,建立联接信息,这导致在不需要的时候传递了大量多余信息。最好的方式是构造一个联接管理器,存放这些全局信息,并在任何需要访问数据库时使用。

 

问题:

持久管理器如何跟踪当前联接的数据库和联接用户?

 

特定约束:

?           所有数据库联接需要访问某个建立联接的地方;

?           引用全局变量可以保持代码简洁明了;

?           维护当前数据库会话,而不是为每个事务创建新会话将更有效且更易调试;

?           在一个地方提供必要的联接信息和操作可以使代码易于理解和维护。

 

解决方案:

创建一个联接管理器对象,存放用户数据库联接所需的所有数据值,共同的值通常是数据库会话、登录到系统的当前用户和其他用于稽核、事务和其他类似的全局信息。

当一个应用系统需要为某些信息只提供一份拷贝,可以使用Singleton模式[GHJV 95]或者使用一个单一活动实例和一个Session[Yoder &Barcalow 97],这个单一活动实例在Design Pattern Smalltalk Companion[MORE HERE 98]中有描述。Singleton通常存放在一个单一全局的地方,例如作为一个类变量或是类本身。不幸的是,这个模式在一个多线程、多用户或分布式的应用时,有时会被破坏。某些情况,需要一个真正的Singleton,而有的情况,每个线程或每个分布的进程可以看作一个独立的应用,它们每个都有自己的Singleton,但是当应用共享一个共同的全局环境时,这个单一全局区域不能被共享,这需要一个机制允许多重Singleton,每个应用一个。因此,联接管理器是管理任何和所用数据库会话的Singleton

联接管理器持久层交互,以让后者得到当前所需的数据库联接。联接管理器也和表管理器交互,为任何建立的联接提供所需的数据库表名。这样,可以再一次使用策略[GHJV 95]模式来选择适当的数据库和表映射。想象一下你可能将你的值保存到五个数据库中,为了速度的考虑,你将选择一个负荷最小的,再用一个批处理过程以一个主数据库同步所有库。这个分布式的数据库系统通过一个策略模式方法,确保用户能够得到一个理想的性能。

 

示例实现:

基于从表管理器得到的信息,联接管理器建立和数据库的联接。当持久层请求一个联接,联接管理器利用数据库部件通过ODBCCLI或其他可能的方式向数据库提供一个接口。一旦当时不能得到联接,或中途中断了,联接管理器提供错误块来进行错误处理,并提供错误收集以记录错误,如有可能就进行恢复。

简单的说,当一个域对象说:

    self databaseConnection

就从联接管理器返回联接,联接类型和哪个联接(如果使用了多个联接)由联接管理器决定。

在我们的例子中,既选择了本地的,也选择了远程的数据库。我们展示了您将如何从VisualAgeABTDbm*类交互,以得到本地数据库的联接。

 

Protocol for Public Interface ConnectionManager (class)

 

databaseConnection

    “检查局部变量,看建立什么联接,或者看返回什么联接。”

    ^self getLocal

       ifTrue: [self localConnection]

       ifFalse: [self remoteConnection]

localConnection

    “返回一个联接给PPLPersistentObject,检查别名看是否已经打开了一个联接,如果没有,创建一个,并提供错误处理,处理联接和联接打开时的错误。”

    | connection |

    (connection :=

       AbtDbmSystem activeDatabaseConnectionWithAlias:‘Example’) isNil

           ifTrue:

           [connection :=

              ((AbtDatabaseConnectionSpec

                  forDbmClass: #AbtOdbcDatabaseManager

                  databaseName: ‘Example’)

                  promptEnalbled: false;

                  connectUsingAlias: ‘Example’

                  logonSpec: (AbtDatabaseLogonSpec

                         id: ‘’

                         password: ‘’

                         server: ‘’)

              ifError:[:error|PPLErrorCollector dbConnectionError])

           autoCommit: false;

       yourself].

       “如果开发环境没有使用错误块,需要提供调试器,在运行期错误块设定为调用错误收集器,它为管理器处理所有dbm类错误,上面的错误块是特定于联接的。”

           connection databaseMgr

       errorBlock: (System startUpClass isRuntime

       ifTrue: [[:error | PPLErrorCollector dbmError:error]]

       ifFalse:[nil]).

    ^connection

 

结论:

?           联接管理器为所有持久对象提供联接信息;

?           当联接信息改变时,只需在一个地方修改;

?           它提供一个支持多联接的方式,可以用于从数据库装载一个对象,或平衡数据库的负荷。

 

相关或交互模式:

?           在多线程、多用户或分布环境中,联接管理器Singleton的替代方法;

?           联接管理器和会话相似,它维护和数据库的会话以及和数据库联接相关的全局信息。

?           联接管理器可以使用一个策略来选择当前联接;

 

已知应用:

?           VisualWorksLens Oracle框架和GemStoneGemBuiler分别有OracleSessionGbsSession,他们都存放事务状态和数据库联接的信息,这个联接管理器在同样的数据库环境中被任何对象引用;

?           Caterpillar/NCSA Financial Model Framework有一个FMState[Yoder 97],当作一个Session并维护联接管理器

?           VisualAgeAbtDbmSystem,维护活动联接的轨迹,联接管理器调用VA类,依次控制物理联接。

?           Illinois Department of Public Health TOTSNewBorn Screening项目。


表管理器

 

别名:

       数据字典

       表映射

 

动机:

随着时间发展,对象对应的持久存储也许会发生变化,或者对象有多个存储。一个表管理器描述了数据库中表和字段的结构,让开发人员远离这些细节,从而做到改变数据库的命名结构却不影响应用开发人员。

 

问题:

一个对象如何知道使用什么表、什么字段,特别是对象需要存入到多个表中时。当使用多个数据库时,又会多出一个数量级的问题。

 

特定约束:

?           将对象映射到关系型数据库,最终需要将对象值映射到数据库表中;

?           当应用系统扩大和修改时,开发人员希望能够快速修改表名;

?           将对象在不同地方,以不同名称映射到同一个表;

?           很容易地从一个数据库切换到另一个;

?           在描述SQL代码的地方直接硬编码表名和字段名非常直接明了。

 

解决方案:

提供一个地方,让对象获取必要的表、字段名以存储自身。当一个对象被存储,在表管理器中查找他的表名。通过只在一个地方定义名称字符串,更改和测试修改变的非常迅速和高效。

这个模式使用一个Sigleton[GHJV 95],将所需的表或字段名称返回给域对象。这个单一实例包含字典结构存放名称,当一个对象发出请求名称的消息,该实例的方法就通过联接管理器检查,决定使用那个字典,使对象可以发送相同的消息,而不管它必须访问那个数据库。

当从多个数据源获取数据,这个模式提供动态改变所访问数据库或表的能力。它灵活地减轻了为多个数据库的相同表一遍一遍编写相同的SQL代码描述的工作,而且仍然可以访问它们。

表管理器在某种意义上,为表映射存放元数据,这个元数据应用于任何一个需要表名的时候,它可以用来动态生成数据库查询。基本上,一个Schema描述了这个映射,每当访问数据库时都需要使用它。

 

示例实现:

表管理器在字典结构中存放表名,在被请求时提供给SQL代码,当表管理器初始化时,字典结构用表名初始化,然后,根据联接管理器,访问适当的字典并返回表名。

当一个域对象说:

    self class table,

TableManager将为类返回表的名称。

 

结论:

?           使用表管理器的一个好处是,当一个表名修改后,代码中只有一个地方需要修改;

?           另一个好处是,可以用不同的名字访问不同数据库的相同表或视图;

?           编写一个表管理器包括要有一种方式解释表和字段的映射,这并不是很容易开发或维护的。

 

相关或交互模式:

?           只要有访问数据库的需要,持久层联接管理器将调用表管理器

?           SQL代码描述将使用表管理器,以将开发者和数据库的变更隔离开;

?           表管理器是一个Singleton

?           表管理器实际上只是一个用元数据描述数据库结构的方式;

?           表管理器能够为复杂映射使用一个翻译器或是为动态系统使用元数据。

 

已知应用:

?           Illinois Department of Public Health TOTSNewBorn Screening项目;

?           很多数据库系统都使用数据字典;

?           VisualWorks ObjectLens使用一个Spec[Foote & Yoder 98],结合Schema来提供表映射。


综合讨论:

现在你已经看到所有的模式,你也许会问,“我如何综合起来用他们?”。所有这些模式一起协作提供一个持久对象映射到数据库中的机制。图2展示了模式之间是如何交互的。持久层为所需持久化域对象的CRUD(创建、读取、更新和删除)操作提供标准接口,持久层使用域对象提供的SQL代码描述构建数据库调用,在生成SQL代码时,持久层表管理器交互以获取正确的数据库表名和字段名。当已经从数据库返回数据值或是将数据写回数据库时,属性值必须映射到数据库字段名,反之亦然,这由属性映射方法完成。属性映射方法SQL代码生成中进行某些类型转换。属性映射和类型映射在持久层实例化一个新对象时也会发生。持久层将一个对象发生变化的值通过联接管理器保存到指定的数据库中,这个变化的值由变更管理器管理;联接管理器能够和表管理器交互,决定使用哪个数据库。持久层在需要进行事务处理时提供对事务管理器的访问。

2 模式交互图

 

一个类场景图(见图3)展示在我们例子中,当从数据库装载值时,对象是如何交互的。一个Name类可以请求load,这个消息将被转发到它的超类PersistentObject。它将从ConnectionManager得到一个联接,接着PersistentObject将生成SQL,为完成这个,他需要向Name请求这个SQL,并从TableManager得到一些表名映射,一旦生成SQL,一个Database Component调用将返回结果集,接着,对每条从数据库返回的行,创建一个新的Name对象,并将这个行的每个字段分配到特定的对象属性中,在映射数据库值到对象属性过程中,数据库类型将被转换到对应的对象类型。一旦完成,PersistentObject将返回一个已创建的Name对象集合。

3 类交互图

 

 


参考

[Ambler 97]

Scott W. Ambler. Mapping Object to Relational Databases. URL:

http:// www.AmbySoft.com/mappingObjects.pdf

[Beck 97]

Kent Beck. SMALLTALK Best Practice Patterns, Prentice Hall PTR, Upper Saddle River , NJ , 1997.

[Brant &

Yoder 96]

John Brant and Joseph Yoder. "Reports," Collected papers from the PLoP '96 and EuroPLoP '96 Conference, Technical Report #wucs-97-07, Dept. of  Computer Science , Washington University Department of Computer Science, February 1997. URL:

http://www.cs.wustl.edu/~schmidt/PLoP-96/yoder.ps.gz.

[BMRSS 96]

Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal. Pattern-Oriented Software Architecture: A System of Patterns, John Wiley and Sons Ltd., Chichester , UK , 1996.

[Foote &

Yoder 96]

Brian Foote & Joseph Yoder. “Evolution, Architecture, and Metamorphosis,” Pattern Languages of Program Design 2, John M. Vlissides, James O. Coplien, and Norman L. Kerth, eds., Addison-Wesley, Reading, MA., 1996.

[Brown &

Whitenack 96]

Kyle Brown & Bruce Whitenack. “Crossing Chasms: A Pattern Language for Object-RDBMS Integration,” Pattern Languages of Program Design 2, John M. Vlissides,James O. Coplien, and Norman L. Kerth, eds., Addison-Wesley, Reading, MA., 1996.

[Foote &

Yoder 98]

Brian Foote & Joseph Yoder. “Metadata,” Submitted to PLoP ’98. URL: http://wwwcat.ncsa.uiuc.edu/~yoder/Research/metadata.

[Fowler 97-1]

Martin Fowler. Analysis Patterns: Reusable Object Models, Addison Wesley, 1997.

[Fowler 97-2]

Martin Fowler. Dealing with Roles, Proceedings of PLoP ’97, Monticello , IL, October

1997. URL: http://www.aw.com/cp/roles2-1.html.

[GHJV 95]

Eric Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns:Elements of Reusable Object-Oriented Software, Addison-Wesley, Reading , MA , 1995.

[GemStone 96]

Gemstone Systems, Inc. GemBuilder for VisualWorks, Version 5. July 1996. URL:

http://www.gemstone.com/Products/gbs.htm.

[GemConn 96]

Gemstone Systems, Inc. GemConnect for VisualWorks, Version 5. July 1996. URL:

http://www.gemstone.com/Products/gbs.htm.

[Keller 97-1]

Wolfgang Keller: Mapping Objects to Tables: A Pattern Language, in “Proceedings of the 1997 European Pattern Languages of Programming Conference,” Irrsee , Germany , Siemens Technical Report 120/SW1/FB 1997.

[Keller 97-2]

Wolfgang Keller, Jens Coldewey: Relational Database Access Layers: A Pattern Language, in “Collected Papers from the PLoP’96 and EuroPLoP’96 Conferences” Washington University , Department of Computer Science, Technical Report WUCS 97-

07, February 1997.

[Keller 98-1]

Wolfgang Keller, Jens Coldewey: Accessing Relational Databases: A Pattern

Language, in Robert Martin, Dirk Riehle, Frank Buschmann (Eds.): Pattern Languages

of Program Design 3. Addison-Wesley 1998.

 

[Keller 98-2]

Wolfgang Keller. “Object/Relational Access Layers - A Roadmap, Missing Links and

More Patterns,” Submitted to EPLoP ’98.

[OE 98]

IBM, Corporation. Object Extender for VisualAge. 1998.

URL: http://www.software.ibm.com/ad/smalltalk/about/persfact.html.

[Orfali &

Harkey 98]

Robert Orfali & Dan Harkey. Client/Server Programming with Java and {CORBA},

2nd Edition, John Wiley & Sons, 1998.

[OS 95]

ObjectShare, Inc. VisualWorks User’s Guide. 1998.

URL: http://www.objectshare.com/vw30abt.htm.

[RSBMZ 98]

Dirk Riehle, Wolf Siberski, Dirk Baeumer, Daniel Megert, & Heinz Zuellighoven.Serializer, in Robert Martin, Dirk Riehle, Frank Buschmann (Eds.): Pattern Languages of Program Design 3. Addison-Wesley 1998.

[TopLink 97-1]

The Object People Inc.: TOPLink Version 4.0 - A White Paper, 1997.

URL: http://www.objectpeople.com/.

[TopLink 97-2]

The Object People Inc.: TOPLink Version 4.0 - User Manual, 1997.

[VA 98]

IBM, Corporation. VisualAge Smalltalk. 1998.

URL: http://www.software.ibm.com/ad/smalltalk.

[Yoder &

Barcalow 97]

Joseph Yoder & Jeffrey Barcalow. "Security," Fourth Conference on Patterns

Languages of Programs (PLoP '97) Monticello , Illinois , September 1997. Technical report #wucs-97-34, Dept. of Computer Science, Washington University Department of Computer Science, September 1997.URL: http://www-cat.ncsa.uiuc.edu/~yoder/papers/patterns/#YoderBarcalow1997.

[Yoder 97]

Joseph Yoder. A Framework to Build Financial Models.

URL: http://www-cat.ncsa.uiuc.edu/~yoder/financial_framework.

[Yoder &

Wilson 98]

Joseph Yoder & Quince Wilson. A Framework for Persisting Objects to Relational Databases. URL: http://www-cat.ncsa.uiuc.edu/~yoder/Research/objectmappings.

[You+ 95]

Joseph Yoder & Quince Wilson. Mainstream Objects, An Analyusis.

URL: http://www-cat.ncsa.uiuc.edu/~yoder/Research/objectmappings.



本文引用通告地址: http://blog.csdn.net/passren/services/trackbacks/30453.aspx
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 总经理离职了作为高管的我怎么办 企业换总经理想换供应商应该怎么办 换了晶振时间还快怎么办 职场两个人都想要你的情况下怎么办 造价起步工资太低又结婚了怎么办 3d保存时写入文件出错怎么办 无经验想在工地承包点小活怎么办 一级建造师挂靠后中标后怎么办 用360对系统修补漏洞很慢怎么办 如果美国和俄罗斯开战中国会怎么办 戴牙冠前临时补牙材料掉了怎么办 设备间在业主家里每次上锁怎么办 成都安全员证原件丢了并过期怎么办 记不施工员证书号了怎么办 优易学车学员版登录不了怎么办 先科移动dvd主板坏了怎么办 离职单位不出劳动解除书怎么办 离职后一级建造师注册证怎么办 京牌货车报废挂靠公司不给办怎么办 二建挂靠注册证书到期了怎么办 二建证书挂靠公司不给钱怎么办 二建拿到证书原单位不解锁怎么办 凯云软件清单锁定只读了怎么办 苹果笔记本鼠标触摸板没反应怎么办 苹果笔记本键盘和触摸板失灵怎么办 苹果手机输入密码显示已停用怎么办 苹果7p手机刷机黑屏了怎么办 苹果5s来电接听屏幕卡顿怎么办? 手机摔了一下触屏失灵怎么办 小米手机摔了一下触屏失灵怎么办 苹果6sp触摸ic坏了怎么办 苹果4s屏幕摔裂了怎么办 新换的手机内屏颜色太亮怎么办 苹果手机摔了一下屏幕失灵怎么办 苹果手机6s屏幕坏了怎么办 苹果6s屏幕摔坏了怎么办 苹果手机屏幕进油了屏幕变暗怎么办 苹果手机不小心屏幕进油了怎么办 苹果6充电插口螺丝口坏了怎么办 苹果5s手机安装屏幕翘边怎么办 苹果手机摔了一下触摸屏失灵怎么办