VF技巧:数据共享程序设计
来源:优易学  2011-8-24 18:43:26   【优易学:中国教育考试门户网】   资料下载   IT书店

 

  事务处理完成了下列锁定动作:
  a、当一个命令直接或间接调用事务时,VFP将强制锁定。任何系统或用户的直接或间接命令将被缓冲,直至ROLLBACK或BEGIN TRANSACTION命令结束事务的操作。
  b、如果在事务处理中使用了锁定命令,如FLOCK()或RLOCK()、则END TRANSACTION语句将不会解锁。因此您必须明确地解除任何在事务处理中进行的明确锁定。应该使包含FLOCK()或RLOCK()命令的事务尽量简短;否则用户会长时间不能访问被锁定的记录。
  4)嵌套事务处理
  对于分隔在不同并发进程中的表,嵌套事务可以为表的更新操作提供逻辑组。事务处理命令BEGIN TRANSACTION…END TRANSACTION不需要在同一函数或过程中。下列规则适用与嵌套事务处理:
  a、可以嵌套5层BEGIN TRANSACTION…END TRANSACTION。
  b、直到最外层的END TRANSACTION被调用时,才执行嵌套事务中的更新。
  c、在嵌套事务中,一个END TRANSACTION只对最近的BEGIN TRANSACTION所引起的事务进行操作。
  d、在嵌套事务中,ROLLBACK语句只对最近的BEGIN TRANSACTION所引起的事务进行操作。
  e、在嵌套事务中,对同一数据的更新操作,最内层的更新优先于嵌套事务处理块中的其他更新。
  请注意下面的示例,因为在嵌套事务中所做的修改没有写入磁盘,而写入事务处理缓冲区,内层事务处理将改写外层事务处理对同一STATUS字段所做的修改。
  BEGIN TRANSACTION &&事务1
  UPDATE EMPLOYEE; &&第一次修改
  SET STATUS="Contrcet" WHERE EMPID BETWEEN 9001 AND 10000
  BEGIN TRANSACTION &&事务2
  UPDATE EMPLOYEE SET STATUS="Exempt" WHERE HIREDATE>{1/1/93} &&改写
  END TRANSACTION &&事务2
  END TRANSACTION &&事务1
  5)保护远程更新
  在对远程表进行数据更新的过程中,事务可以避免系统造成的错误。
  6)性能管理
  如果有一个能够正常工作的多用户应用程序,可以采用下面的方法提高程序性能:
  a、将临时文件放在本地驱动器上:VFP在默认文件夹下创建自己的临时文件。文本编辑工作期也临时地创建被编辑文件的备份(一个.BAK文件)。如果本地工作站的硬盘上有足够的剩余空间,将临时文件放在这个本地盘或RAM驱动器上可以提高程序性能。重定向这些文件到本地盘或RAM驱动器上,可以减少访问网络驱动器的次数,从而提高性能。也可以在配置文件CONFIG.FPW中使用EDITWORK、SORTWORK、PROGWORK及TMPFILES语句,为这些文件指定其他存放的位置。
  b、在排序和索引文件之间选择:当一个表中的数据相对稳定时,处理没有设置索引顺序的表会提高性能,这并不意味着已经经过排序整理的表就不能或不应该利用索引文件,象SEEK命令就需要一个索引,而且在定位记录时速度相当快。但是,一旦用SEEK完成定位操作后,就应该关闭索引。
  c、安排对文件的独占访问:对于在其他用户不访问数据时运行的命令,象夜间的更新操作,可以通过独占方式打开文件提高性能。当文件以独占方式打开时,由于VFP不需要测试记录或文件锁定的状态,因此性能得到提高。
  d、控制锁定文件的时间:要减少用户对表或记录写操作的竞争,就必须减少锁定记录或锁定表的时间。可以通过在编辑完成之后的非编辑过程中锁定记录来做到这一点。开放式记录缓冲锁定时间最短。
  3、使用视图管理更新
  可以使用视图具有的更新冲突管理技术来管理多用户对数据的访问。使用WhereType属性,视图控制发送到基于视图的基表的内容。可以为本地和远程视图设置该属性。WhereType属性提供了四种设置:
  DB-KEY
  DB-KEYANDUPDATABLE
  DB-KEYANDMODIFIED(默认)
  DB-KEYANDTIMESTAMP
  通过选择四种设置之一,可以控制VFP如何生成发送到视图基表的SQL Update语句的WHERE子句。可以使用“视图设计器”的“更新条件”选项卡来选择需要的设置,或者使用DBSETPROP()函数设置一个视图定义的WhereType属性。要想更改一个活动视图临时表的WhereType属性,请使用CURSORSETPROP()。
  1)只比较关键字段
  使用DB-KEY设置对更新的限制最小。用来更新远程表的WHERE子句只包含用KeyField或KeyFieldList属性指定的主关键字段。如果基表中的主关键字段的值在检索记录之后没有被更改或删除,更新将正常进行。
  2)比较视图中的主关键字段和已更改字段
  默认的DB-KEYANDMODIFIED设置比DB-KEY多了一些限制。DB-KEYANDMODIFIED只将关键字段和在视图中更改的可更新字段与基表相应的字段进行比较。如果在视图中更改了一个字段,但该字段不是可更新字段,则字段不与基表中的数据比较。
  用来更新基表的WHERE子句包含用KeyField属性指定的主关键字段和其他在视图中更改的任意字段。
  3)比较关键字段和所有可更新字段
  DB-KEYANDUPDATABLE设置将关键字段以及任何视图中的可更新字段(不管是否被修改)与基表相对应的的字段进行比较。如果字段是可更新的,即使在视图中并没有更改它,但如果其他人在基表中更改了这个字段,更新就会失败。
  用来更新基表的WHERE子句包含用KeyField或KeyFieldList属性指定的主关键字段和其他任何可更新字段。
  4)比较基表记录中所有字段的时间戳
  DB-KEYANDTIMESTAMP设置是对更新的限制最多的,并且只有在基表中具有时间戳字段时才能使用该设置。VFP将基表记录中的当前时间戳与当数据被提取到视图中的时间戳进行比较。如果基表记录的任何字段被改变了,即使它不是视图更改的字段,甚至不是视图中的一个字段,更新也会失败。
  为了能够在多表视图中使用DB-KEYANDTIMESTAMP设置成功地更新数据,必须在每个可更新表的视图中包含时间戳字段。例如,在视图中有三个表,但是却只想更新其中的两个,而且选择了DB-KEYANDTIMESTAMP设置,必须从两个可更新表中将时间戳字段带入到结果集合中。可以使用CompareMemo属性的逻辑值来确定在冲突检查中是否包含备注字段。
  三、冲突管理
  不管选择了缓冲、事务还是视图、都必须在更新过程中管理冲突。那么,如何具体管理冲突呢?
  1、管理缓冲冲突
  在一个多用户环境中,通过精心选择打开、缓冲并锁定数据的时间和方式,可以更高效地进行数据更新操作。应该减少访问记录或表时发生冲突的时间,同时必须预测到不可避免的的冲突将导致什么样的后果,并对这种冲突进行管理。冲突一般在一个用户试图锁定一个当前正被其他用户锁定的记录或表时发生,两个用户不能同时锁定同一个表或记录。
  应用程序中应包含管理冲突的例程。如果没有冲突例程,系统将死锁。死锁通常在这种情况下发生:第一个用户已经锁定一个表或记录,现在试图去锁定已被第二个用户锁定的记录或表,而第二个用户又反过来试图锁定第一个用户锁定的记录或表。尽管这种情况很少发生,但记录或表锁定的时间越长,这种死锁的可能性就越大。
  无论是设计一个多用户的应用程序还是为一个单用户系统添加网络支持服务,都要求找到错误并对其进行处理。使用VFP记录缓冲和表缓冲可以简化这种工作。
  如果试图锁定一个已被其他用户锁定的记录或表,VFP将返回错误信息。可使用SET REPROCESS自动处理不成功的锁定操作。此命令可与ON ERROR例程和RETRY命令组合,继续或取消锁定操作。
  2、检测并解决冲突
  在数据更新操作过程中,特别是在共享环境下,您可能希望确定哪些字段已经被更改、确定已更改字段的原有值或当前值是什么。VFP的缓冲和GETFLDSTATE()、GETNEXTMODIFIED()、OLDVAL()及CURVAL()函数可以提供这些功能。通过它们来确定哪些字段已经被更改;查找已更改的数据;比较当前值、原有值及已编辑的值。这样,可以决定如何处理错误或冲突。
  如果要检测字段中所做的更改,可在更新操作之后使用GETFLDSTATE()函数。GETFLDSTATE()可以对非缓冲数据进行操作,但在启用了记录缓冲的情况下,此函数更加有效。比如将GETFLDSTATE()用于一个表单的Skip按钮代码中。当您移动记录指针时,VFP将检查记录中所有字段的状态,如下例所示:
  lModified=.F.
  FOR nFieldNum=1 TO FCOUNT() &&检查所有的字段
  IF GETFLDSTATE(nFieldNum)=2 &&已修改
  lModified=.T.
  EXIT &&可以在此处插入一个
  ENDIF
  ENDFOR
  若要检测并定位缓冲数据中已更改的记录,请使用GETNEXTMODIFIED()函数。GETNEXTMODIFIED()函数以0作为参数,查找第一个已修改的记录。如果其他用户对缓冲表进行了修改,则您的缓冲区中TABLEUPDATE()命令遇到任何修改都将导致冲突。可以用CURVAL()、OLDVAL()和MESSAGEBOX()计算冲突值并解决冲突,CURVAL()返回磁盘上记录的当前值,而OLDVAL()返回记录缓冲时的值。
  若要确定缓冲字段的原有值,请使用OLDVAL()函数,OLDVAL()返回一个缓冲字段的值。
  若要确定磁盘上一个缓冲字段的当前值,请使用CURVAL()函数,CURVAL()返回一个在编辑操作执行前磁盘缓冲字段的当前值。
  在共享环境中,可以创建一个出错处理过程,比较当前值和原有值,并决定是接受当前的修改还是更早一点的修改。
  1)使用备注字段检测冲突
  使用CompareMemo属性来控制何时使用备注字段检查更新冲突。这个视图和临时表属性确定了在更新的WHERE子句中是否包含备注字段(备注或通用型)。默认设置是.T.,即在WHERE子句中包含备注字段。如果这个属性设置为.F.,不论UpdateType如何设置,在更新的WHERE子句中就不会包含备注字段。
  当CompareMemo属性设置为假时,备注字段上的开放式冲突检查是不可用的。如果要用备注字段的冲突检查,请将CompareMemo属性设置为真。
  2)管理冲突的规则
  管理在多用户环境中的冲突需要有扩展和可重用的代码。一个完整的冲突管理例程进行如下操作:
  a、检查冲突;
  b、确定冲突的性质和位置;
  c、提供足够的信息,用户可以有效地解决这些冲突;
  有关冲突管理例程的示例,可以参阅位于VFP\SAMPLES\CLASSES的SAMPLES.VCX中的datachecker类。将该类添加到表单中,在将缓冲数据写入表的操作之前调用CheckConflicts方法程序,例如记录缓冲移动记录指针,关闭表,或者发出TABLEUPDATE()命令。

上一页  [1] [2] [3] [4] 

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训