使用特殊的技术更新数据库(ABAP)
一,过程
1,DIALOG程序获得用户要更新的数据,并把它写到一个特殊的LOG TABLE,表内的条目属于同一个请求类型,包含了稍后将要写到数据库的数据。一个DIALOG程序可以写多条数据到LOG TABLE。写进LOG TABLE里的条目属于同一个LUW,意思就是它们要么都被执行,要么都不被执行。
2,DIALOG程序关闭LUW(将LOG TABLE的条目打包),并通知系统基本程序有一个包的数据需要更新。
3,系统基本程序从LOG TABLE读取这个LUW的需要更新的数据,并把这些数据提供给系统更新程序。
4,系统更新程序接受传输给它的数据,并更新数据库。
5,如果更新程序运行成功,系统基本程序删除这个LUW在LOG TABLE的所有数据;如果失败,保持LOG TABLE的这些数据,并标记不成功。触发更新程序的用户会收到系统发的关于这个错误的E-MAIL。可以用参数rdisp/vbmail(1发,0不发)来控制错误时是否发E-MAIL和rdisp/vb_mail_user_list($ACTUSER代表创建更新数据的用户)来控制错误时发E-MAIL给谁。可以用事务SM13来监控更新请求。
二,技术实现
更新程序必须用一个特殊的FM(update module)来实现。UPDATE MODULE和其他的FM一样,有传输参数的接口,但是只能有IMPORTING和TABLES,并且类型只能用参考或者结构。EXPORTING和EXCEPTION参数在UPDATE MODULE里是被忽略的。UPDATE MODULE里包含实际的数据库更新语句。
在DIALOG程序中,通过一个特别的FM,使用IN UPDATE TASK。如:
CALL FUNCTON ‘F1‘ IN UPDATE TASK
EXPORTING
P1 = A
P2 = B.
使用这样写法的FM不会立即执行,而是写进LOG TABLE,作为一个执行请求,一个SAP LUW下的更新请求存储在同一个UPDATE KEY下。对一个SAP LUW来说UPDATE KEY是一个唯一的世界范围的识别码,意思就是一个SAP LUW的UPDATE KEY是唯一的,不会和另外的SAP LUW的UPDATE KEY重复。
只有当程序执行到COMMIT WORK的时候,才会为这些请求创建一个抬头条目LOG HEADER,表示以上这些同样UPDATE KEY的属于同一个包,然后系统关闭这个LUW。当LOG HEADER创建以后,系统通知DISPATCHER有一个更新包已经准备好可以处理了。
有些时候,你可能需要丢弃当前SAP LUW的所有changes(比如结束TCODE),可以使用ROLLBACK WORK或者弹出一个A类型的MESSAGE,这两个语句都可以有以下的效果:
-删除写到该点之前的所有的change requests
-删除写到该点之前所有的锁
-丢弃当前DB LUW执行的changes
-丢弃所有使用POC形式登记的subroutines
ROLLBACK WORK语句不会影响程序上下文,意思就是,所有的数据对象保持不变。UPDATE MODULE里面不允许有显示的ROLLBACK WORK或者COMMIT WORK语句。
如果更新失败,属于这个SAP LUW的LOG条目会标记成不正确,同时错误消息也会保存到日志。可以用SM13来检查LOG条目。
如果在DIALOG程序里为更新技术设置了锁,并且锁的参数_scope = 2,那么使用COMMIT WORK之后锁会被传递到UPDATE TASK,这个时候在DIALOG程序中,锁不能被访问。
在UPDATE MODULE里不必显示的去释放锁,因为更新处理的最后阶段,系统会自动释放这些锁。当UPDATE TASK有错误发生的时候,也会自动释放锁。
如果UPDATE MODULE允许更新请求再次被处理,在处理的时候数据库中的数据表跟失败的时候可能不一样,而且也没有锁保护了,因为错误产生的时候,锁自动被释放了。
举个例子,如果一个凭证没有成功更新到数据库是因为数据库的表空间溢出,这个时候比较适合再次处理。
三,更新的模式
1,异步模式
在这个模式下,DIALOG程序和UPDATE程序各自运行。DIALOG程序写请求到LOG TABLE,用一个COMMIT WORK来关闭LUW。UPDATE程序被COMMIT触发并开始运行来处理这些请求,DIALOG程序继续运行,不会等待UPDATE程序结束。UPDATE程序在特殊的UPDATE WORK PROCESS中运行。
当数据库更新花费比较长的时间,用户DIALOG需要较少的响应时间,异步更新显得比较重要。在DIALOG处理中,异步更新是标准的技术,意思就是DIALOG程序一般会采取异步更新方式。
可以用VBLOG这个簇表来实现LOG TABLE,或者用透明表VBHDR,VBMOD,VBDATA,VBERROR来替代它。
2,同步模式
可以用COMMIT WORK AND WAIT语句来触发一个同步更新,DIALOG程序要等待UPDATE程序结束再进行下一步的处理。
如果后续处理或者DIALOG程序的结束需要依靠更新的结果,这个时候要用同步模式。可以用SY-SUBRC来检查同步更新的执行情况,在程序等待UPDATE程序执行的过程中,DIALOG程序的DIALOG WORK PROCESS被释放,当更新结束之后,系统重新为DIALOG程序分配一个新的空闲的DIALOG WORK PROCESS做下一步的处理。
3,本地模式
使用SET UPDATE TASK LOCAL语句来使用UPDATE MODULE在本地执行,同样的用COMMIT WORK来关闭SAP LUW,更新会在同一个DIALOG WORK PROCESS中进行,DIALOG程序等待更新完成(同步)。当LOCAL UPDATE完成之后,会提交一个显示的DB COMMIT,DIALOG程序也得以继续执行。
如果更新执行有错误,并且其中一个UPDATE MODULE发出一个终止程序的MESSAGE,系统会执行一个自动的DB ROLLBACK来丢弃这个SAP LUW所有的改变,并且DIALOG程序会终止,并弹出一个程序终止信息。
LOCAL UPDATE模式中,更新请求不会写到VBLOG表中,而是在MAIN MEMORY中,因为没有IO的访问,其速度要比同步和异步模式的快一点。LOCAL UPDATE只适合批量模式。
SET UPDATE TASK LOCAL工作到遇到COMMIT WORK语句,意思就是COMMIT WORK执行之后,SET UPDATE TASK LOCAL不再有效。
四,UPDATE MODULE的类型(V1&V2)
FUNCTION MODULE的processing type有三种,NORMAL FUCNTION MODULE,REMOTE-CAPABLE MODULE和UPDATE MODULE。每种下面又包含4种分类,立即启动,立即启动(不可重启),延迟启动,collective run.前2种属于V1类型,后两种属于V2类型。
UPDATE MODULE的类型决定了其处理的模式。所有的DIALOG程序里的V1请求都会在单独的DB LUW里执行。只有当V1执行成功之后才会处理V2请求,V2也会在单独的LUWS里执行。
V2类型的UPDATE MODULE处理的DB CHANGES一般都是紧接着V1的CHANGES(MAIN CHANGES)之后进行的。
V1类型的UPDATE MODULE分可重新启动或不可重新启动的两种。V2类型的当发生错误的时候总是可以重新启动,再次处理。
V2类型的COLLECTIVE RUN是SAP内部使用。相应的V2请求并不是在V1执行之后直接执行,而仅仅是在程序RSM13005被调用之后才执行。
V1请求都是由V1类型的UPDATE MODULE来创建的,对于同步异步模式来说,V1类型的UPDATE MODULE都会把请求创建到VBLOG这个TABLE,对于本地更新模式来说,V1请求是在MAIN MEMORY中创建的。V2类型的请求总是创建到VBLOG表中。
V1请求都会在一个V1类型的UPDATE WORK PROCESS(UPD)作为一个单独的DB LUW来处理。如果V1更新成功,系统会删除V1的请求和所有在V1更新任务上的锁,并设置一个DB COMMIT,然后触发V2更新。
V2请求也是在一个V2类型的UPDATE WORK PROCESS(UPD2)作为一个单独的DB LUW来处理。如果SAP系统没有设置V2类型的UPDATE WORK PROCESS,则V2请求会在一个V1类型的UPDATE WORK PROCESS里进行处理。如果V2请求处理成功,将会从VBLOG删除相关的请求,并设置一个DB COMMIT。V2请求一般都会运行在没有锁的情况下,因为这些锁在V1完成之后就被删除掉了。因此,V2更新总是运行在没有SAP LOCKS的情况下。
如果V1 UPDATE MODULE用一个终止消息终止了V1更新,那么V1更新任务上的锁讲被删除,数据库将ROLLBACK,一个E-MAIL会发送给创建这个LUW的用户,并且V1请求在VBLOG表中被标记为不正确。V2更新也就不会被触发。
当然如果V2 UPDATE MODULE终止了V2更新,同样的,数据库ROLLBACK,属于这个SAP LUW的V2更新都不会执行,V2请求在VBLOG表中被标记为不正确。
DIALOG程序用_SCOPE = 2创建的锁会被传递到V1更新任务中,在V1更新的结束,不管V1更新是否成功或者终止,都会把这些锁自动删除。因此,在DIALOG程序中不能显式的删除这些锁(太早),或者在UPDATE MODULE里删除(没必要)。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。