📄 206.htm
字号:
(有些属性值的名称和ADO中定义的不同),这些属性包含:</span><span id=Layer184></font></p><font size=2 color=#3c3c3c face=arial><ul><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b> adXactReadUncommitted/adXactBrowse</span><span id=Layer185> </b></font>交易可以读取资料库目前的值,即使这些值已被其它尚未确认的交易所改变。这有时称为dirty read,它可以增加不需看到完全一致的资料之应用程式的执行效能,如某些决策支援解决方案。因为用户端并不需要等待锁定释放後就可以取得资料。不过有许多,或许是大部份,应用程式并不会使用这个选项。存取交易中间状态的资料在某些地方是违反了交易的概念,也可能产生不正确地结果。</span><span id=Layer186></li><br></font><br><font size=2 color=#3c3c3c face=arial><hr><font face=Arial Black color=#3e77d7 size=3><b> 附注</b></font><p><font size=2 color=#3c3c3c face=arial>交易定义中通常拥有ACID属性。这些缩写字是:Atomic,代表交易中所有的动作都会执行,或者全部不执行;Consistent,交易在逻辑上正确地更改牵涉到的资料;Isolated,当交易在中间状态时,没有交易可以看到其它交易内的资料;Durable,暗喻在交易後,硬体或软体故障时并不会改变交易的结果。实际上,隔离(isolation)的等级是由客户端所选择的,这些属性并不会保留这个值。</span><span id=Layer187></font></p><hr></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b> adXactReadCommitted/adXactCursorStability</span><span id=Layer188> </b></font>这个交易无法读取其它交易已更改但未确认的资料,这也就是说,没有dirty read的可能。也就是交易希望做到了,同时它也是ADO的预设值。不过,如果客户端在一个交易中查看同样的资料两次,资料可能会看起来不同,也会产生所谓的非重复读取(nonrepeatable read)。这是因为很可能就在这一段时间里,使用这个资料的其它交易已确认了,因此在这两次读取之间可能会新增横列,或更改横列中的值。</span><span id=Layer189></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b> adXactRepeatableRead</span><span id=Layer190> </b></font>类似adXactReadCommitted,这个交易不会读取其它交易已改变而未确认的资料。再者,若客户端在同一个交易中查看同样的资料两次,这个隔离等级不会让客户端看到在两次存取资料的时间内,其它已确认的交易对资料进行的变动。换句话说,客户端不会遭遇dirty read或非重复读取的可能。然而,若客户端在一个单独的交易中查看同样的资料两次,第二次读取时仍旧会看到其它同时执行的交易已确认的新横列。这些新增的横列有时称为鬼影(phantom)。</span><span id=Layer191></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b> adXactSerializable/adXactIsolated</span><span id=Layer192> </b></font>这个交易将看不到其它交易进行的任何变动。即使客户端在同一个交易中查看相同的资料两次,同时其它已确认的交易在两次查看的期间修改了资料,或新增新横列,这个隔离等级能确保其它的客户端不会看到这些变动的资料。换句话说,使用这个隔离等级的客户端发行的查询能够确保不会遇到dirty read,非重复读取,或鬼影。</span><span id=Layer193></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b> adXactChaos</span><span id=Layer194> </b></font>若感兴趣的资料是属於目前较高隔离等级的交易之一部份,则客户端可以看到这个交易物件的IsolationLevel属性值。可是客户端不允许变动那些资料。</span><span id=Layer195></li><br></font><font size=2 face=arial color=#3c3c3c><li><font size=2 face=arial color=#3e80d7><b> adXactUnspecified</span><span id=Layer196> </b></font>这个值是由底层资料提供者所回传的,它代表提供者(provider)无法判断正在使用的隔离等级是哪一种。</span><span id=Layer197></li><br></font></ul></font><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>一个交易是否可以看到其它交易使用中的资料是由Connection 物件的Isolation-Level 属性来控制的</span><span id=Layer198></font></p><hr><p><font size=2 color=#3c3c3c face=arial>资料来源并不需要支援所有的IsolationLevel值。若特定的资料提供者(data provider)并不支援所要求的隔离等级,则此提供者可以回传一个较高等级的隔离动作。举例来说,若客户端要求使用adXactRepeatableRead,而底层的DBMS并不支 援这个选项,则Connection物件的IsolationLevel属性可能会被设定成adXactSerializable,更高一层的隔离等级。若provider提供的话,ADO同样也允许巢状交易。客户端可以开始一个交易,然後在此交易内再开启一个新交易。巢状交易是个很吸引人的东西,不过要小心,许多资料来源并不支援。</span><span id=Layer199></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>资料来源并不须要支援定义在Isolation-Level中的每一个值</span><span id=Layer200></font></p><hr><p><font size=2 color=#3c3c3c face=arial>关於ADO控制交易的methods还有一点要注意:许多,甚至是大部份的ADO客户端从来就不会使用它们。取代的做法,叁层式应用程式将会使用COM+提供的交易能力。COM+应用程式中永远都不应该呼叫BeginTrans、CommitTrans或RollbackTrans(如果这样做,这个呼叫会回传错误。)交易的开始与结束是由COM runtime程式库进行的,将在</span><span id=Layer201> <a href=208.htm# target=_new>第八章</span><span id=Layer202></a> 描述。</span><span id=Layer203></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>ADO客户端经常使用COM+交易,而不会使用Connection物件来控制交易</span><span id=Layer204></font></p><hr><font color=#3e72d7 face=arial size=4><b>关闭一个连线</span><span id=Layer205></b></font><p><font size=2 color=#3c3c3c face=arial>若要关闭一个关联至Connection物件的连线,客户端可以呼叫Connection物件的Close method。如前面所描述,你也可能在不明确指定使用一个Connection物件的情况下,建立一条连线,只要呼叫Recordset的Open method就行了。以这个方式开启的连线可经由呼叫Recordset的Close method关闭。</span><span id=Layer206></font></p><font color=#3e72d7 face=arial size=4><b>连接共用区(Connection Pooling)</span><span id=Layer207></b></font><p><font size=2 color=#3c3c3c face=arial>不管如何开启、关闭一个资料连线,这种行为天生就是一个昂贵的动作(「昂贵」这个字是「慢」这个字的婉转说法)。其中一种客户端可采取的解决方案便是开启一条连线,在必要时才使用它,然後在客户端完成它的工作时关闭之。对於许多类型的客户端这样已足够了,它也是二层式应用程式的常见解决方案。不过对於交易性的COM物件(这是一种重要的ADO客户端类别)来说,要求并掌握住一条资料库连线通常是件不可能的事。关於理由将在</span><span id=Layer208> <a href=208.htm# target=_new>第八章</span><span id=Layer209></a> 中描述。这些物件通常不会使用这样的方式运作。取代的作法是:它们必须经常要求与释放资料库连线。若要这个动作更有效率一些, ODBC与OLE DB(以及ADP)两者都须支援连接共用区(connection pooling)。</span><span id=Layer210></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>要求连线与释放连线的动作可能很慢</span><span id=Layer211></font></p><hr><p><font size=2 color=#3c3c3c face=arial>这个概念是很简单的。当一个ADO客户端第一次要求一条到特定DBMS的连线时,底层的OLE DB provider 必须真正地建立一条新连线。不过当客户端关闭连线时,这条连线并没有真正被毁灭。取代的做法,这条仍开启中的连线将会被放到OLE DB Pool Manager所维护的连接共用区。下次这个行程中的客户端需要一条到这个资料库的连线时,它便可以重复使用其中的连线,而不必建立一条新连线。图6-10展示运作的过程。</span><span id=Layer212></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>为了加速,开启的连线必须放到共用区并能重复使用</span><span id=Layer213></font></p><hr><br><center><a target=_new href=imagesh/6-10.gif><img border=0 src='imagesl/6-10.gif'></a></center></span><span id=Layer214><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b> 图 6-10</span><span id=Layer215> </b></font>资料库连线放在共用区,可重复使用以提升执行效能。</span><span id=Layer216></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>放在共用区的资料库连线是个不错的方式,它可以有效地增进执行效能。不过有些限制得牢记在心。第一,连线只有在相同行程中的客户端才可以共享,连接共用区并不能够跨行程边界。同样地,客户端只有在连线能符合客户端的需求时,才能够重复使用资料库连线。即使当时共用区已存在着连线,但安全性需求不符合潜在的新客户端,则客户端便不能使用这个连线。</span><span id=Layer217></font></p><font color=#3e72d7 face=arial size=4><b>离线Recordset(Disconnected Recordset)</span><span id=Layer218></b></font><p><font size=2 color=#3c3c3c face=arial>讨论截至目前为止,Recordset物件永远会关联到一条连结到某些资料来源的开启的连线。然而,ADO客户端有可能会建立并繁衍一个Recordset,然後释放关联到它的连线。Recordset物件可由没有关联到连线的客户端维护,因此它被称做为离线Recordset。离线Recordset通常用在透过DCOM,从中间层传送资料到桌上型的客户端,在此所描述的都是以此为前提。</span><span id=Layer219></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>一个离线Rec-ordset可以用在从中间层传递资料到桌上型电脑</span><span id=Layer220></font></p><hr><p><font size=2 color=#3c3c3c face=arial>若要建立一个离线Recordset,ADO客户端(如执行在中间层伺服器上的COM物件)首先设定Connection物件或Recordset物件的CursorLocation属性,以便指明欲使用一个客户端的cursor。然後客户端便以一般的方式开启一条连线,繁衍Recordset,然後释放这个连线。现在指向这个Recordset的介面指标便被传送到桌上型电脑上的客户端。</span><span id=Layer221></font></p><p><font size=2 color=#3c3c3c face=arial>不过,当指向离线Recordset物件的介面指标跨网路传送到桌上型电脑上的客户端时,整个Recordset 内容与所有的东西 都会传送过去,不仅只有指标而已。(在技术的背後,这个动作依赖COM自订的包装动作,但这个过程ADO客户端是看不到的。如此让传递一个离线Recordset(它包含的资料是从叁层式应用程式的中间层取得的)到桌上型客户端的动作更为简单。</span><span id=Layer222></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>传递一个介面指标到离线的Reocrdset,也会传送Rec-ordset的内容</span><span id=Layer223></font></p><hr><p><font size=2 color=#3c3c3c face=arial>一旦接收到Recordset,客户端可以修改它包含的资料,然後将变更的部份套用到资料来源。若要达到这个目的,客户端传递更改过的Recordset回到中间层。(再次强调,客户端只传递介面指标,但实际上Recordset整个内容也会传送。)然後中间层的COM物件可以呼叫Recordset的Open method重新连结到资料来源。一旦完成这个工作,COM物件便会呼叫Recordset的UpdateBatch method,然後将变动的部份套用到资料来源。图6-11展示这个过程运作的样子。</span><span id=Layer224></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>离线Record-set也可以用来修改资料</span><span id=Layer225></font></p><hr><br><center><a target=_new href=imagesh/6-11.gif><img border=0 src='imagesl/6-11.gif'></a></center></span><span id=Layer226><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b> 图 6-11</span><span id=Layer227> </b></font>一个离线Recordset可以跨网路传送到桌上型电脑,进行修改,然後用来更新资料来源。</span><span id=Layer228></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>一个离线Recordset不能够维护底层资料库资料的锁定,它连结到资料库的连线已消失。如此让离线Recordset无法使用悲观锁定。若客户端希望修改离线Recordset中的横列,然後将变动的部份套用到资料来源,则Recordset的LockType必须设定为BatchOptimistic。就和乐观锁定一样,自从Recordset繁衍後,正在修改的资料有可能会改变。若发生这种情况,则呼叫UpdateBatch会回传一或多个错误给客户端。不过先不管这个限制,离线Recordset是很有用的,特别是在叁层式的应用程式中。</span><span id=Layer229></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -