你们能够关注个人公众号,公众号里的排版更好,阅读更温馨。html
使用特殊的技术更新数据库(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里删除(不必)。异步