标签:
外围系统调用导致锁丢失
Related:
? ?
Article 1
2014年4月6日
22:04
? ?
SAP锁机制
? ?
一、SAP为什么要设置锁:
?? 1,保持数据的一致性
???? 如果几个用户要访问同样的资源,需要找到一种同步访问的方法去保持数据的一致性。比如说,在航班预订系
统中,需要检查还有没有空座位,当检查的时候,你不想别人修改重要的数据(空座位的数量)。
?? 2,仅仅用Database锁是不够的
???? 数据库管理系统物理锁定了要修改的行记录,其他用户要等到数据库锁释放才能访问这个记录。
???? 在SAP系统中,当一个新屏幕显示的时候会释放掉Database锁,因为屏幕的改变会触发一个隐式的DB COMMIT
。如果数据是从好几个屏幕收集来的话,而且在这段时间内这些数据会分别被锁定,仅仅用Database锁就不够了。
???? SAP系统在应用服务器层面有一个全局的LOCK TABLE,可以用来设置逻辑锁来锁定相关的表条目,并有
ENQUEUE工作进程来管理这些锁。SAP锁是一种逻辑意义上的锁,有可能你锁定的表条目在DATABASE上根本就
不存在。
? ?
二、锁对象和其对应的Function Module
??? 在SE11里创建锁对象,自定义的锁对象都必须以EZ或者EY开头来命名。一个锁对象里只包含一个PRIMARY
TABLE,可以包含若干个SECONDARY TABLE,锁的模式有三种:E,S,X。LOCK PARAMETERS里填写你要根
据哪些字段来锁定表条目。
??? 模式E:当更改数据的时候设置为此模式。
??? 模式S:本身不需要更改数据,但是希望显示的数据不被别人更改。
??? 模式X:和E类似,但是不允许累加,完全独占。
??? 如果你在一个程序里成功对一个锁对象加锁之后,如果模式为E,其他用户不能再对这个锁对象加E、X、S模式
的任意一种锁;
??? 如果你在一个程序里成功对一个锁对象加锁之后,如果模式为X,其他用户不能再对这个锁对象加E、X、S模式
的任意一种锁;
??? 如果你在一个程序里成功对一个锁对象加锁之后,如果模式为S,其他用户不能再对这个锁对象加E、X模式的
锁,但是可以加S模式的锁;
??? 如果你在一个程序里成功对一个锁对象加锁之后,如果模式为E,在这个程序,你还可以再对这个锁对象加E、
S模式的锁,X模式的不可以。
??? 如果你在一个程序里成功对一个锁对象加锁之后,如果模式为X,在这个程序,你不可以再对这个锁对象加E、
X、S模式的锁。
??? 如果你在一个程序里成功对一个锁对象加锁之后,如果模式为S,在这个程序,你还可以再对这个锁对象加S模
式的锁,如果没有别的用户对其加S模式的锁,那么你还可以对其加E模式的锁。X模式的不可以。
??? 当激活锁对象的时候,系统会自动创建两个FM,ENQUEUE_<锁对象名>和DEQUEUE_<锁对象名>,分别用来锁
定和解锁。
? ?
三、锁定和解锁
??? 当用逻辑锁来锁定表条目的时候,系统会自动向LOCK TABLE中写入记录。
??? 当调用设置锁的FM时,LOCK PARAMETERS如果没有指明,系统会锁定整个表。当然,LOCK PARAMETER:
CLIENT有点特殊,如果不指定,默认是SY-MANDT;如果指定相应的CLIENT,会锁定对应CLIENT上的相应的表
记录;如果设置为SPACE,则锁定涉及所有的CLIENT。
??? 当逻辑锁设置失败后,一般会有两种例外。一个是EXCEPTION:FOREIGN_LOCK,意思是已经被锁定了;另一
个是EXCEPTION:SYSTEM_FAILURE。
??? 有些情况下,程序中设置成功的逻辑锁会隐式的自己解锁。比如说程序结束发生的时候(MESSAGE TYPE为A
或者X的时候),使用语句LEAVE PROGRAM,LEAVE TO TRANSACTION,或者在命令行输入/n回车以后。
??? 在程序的结束可以用DEQUEUE FUNCTION MODULE来解锁(当然如果你不写这个,程序结束的时候也会自动的
解锁),这个时候,系统会自动从LOCK TABLE把相应的记录删除。使用DEQUEUE FUNCTION MODULE来解锁的
时候,不会产生EXCEPTION。要解开你在程序中创建的所有的逻辑锁,可以用FM:DEQUEUE_ALL.
??? ?
四、上锁的一般步骤
??? 先上锁,上锁成功之后,从数据库取数据,然后更改数据,接着更新到数据库,最后解锁。按照这个步骤,才
能保证更改完全运行在锁的保护机制下。
? ?
From <http://scnblogs.techweb.com.cn/abap/archives/6.html>
? ?
Article 2
2014年4月6日
22:05
? ?
Article 2:
由于工作的需要,最近在研究业务系统数据并发控制问题,曾经写过abap程序,记得sap里有个锁对象,可以对表记录进行锁定操作,于是进行了相关了解,并在此基础上设计了基于MC的锁机制(有时间再献上基于MC的锁机制,供大家批判)。如果觉得下文所述,似曾相识,说明大家对sap所对象的理解已经超越我。
???????sap为了同步同时多个用户操作同一数据,防止数据出现不一致性而采用了锁机制。一般?sap会在操作数据前设置锁,防止第二个用户进行修改操作,当操作结束后系统会自动释放锁(当然程序也可以调用解锁函数去解锁)。
???????1、SAP锁的类型
???????1)Exclusive lock
???????The locked data can be read or processed by one user only. A request for another exclusive lock or for a shared lock is rejected.
???????2)Shared lock
???????Several users can read the same data at the same time, but as soon as a user edits the data, a second user can no longer access this data. Requests for further shared locks are accepted, even if they are issued by different users, but exclusive locks are rejected.
???????3)Exclusive but not cumulative lock
???????Exclusive locks can be requested by the same transaction more than once and handled successively, but an exclusive but not cumulative lock can only be requested once by a given transaction. All other lock requests are rejected.
? ?
???????2、TCODE、相关表、多表锁
???????1)TCODE:可以通过se11来查看和创建锁对象,锁对象创建完毕之后,统会自动创建两个FM,ENQUEUE_<锁对象名>和DEQUEUE_<锁对象名>,分别用来锁定和解锁。
???????2)相关表:
??????DD25L:组合标题(方式,MC目标,锁定目标)(纪录了锁主表);
??????DD25T:
??????DD26S:视图的基本表和外来码关系(纪录了所有和锁相关的表);
??????DD27S:合计(视图,MC对象,锁定对象)字段;
??????3)多表锁
??????在SE11里创建锁对象,自定义的锁对象都必须以EZ或者EY开头来命名。一个锁对象里只包含一个PRIMARY TABLE,可以包含若干个SECONDARY TABLE。如多表锁:EMEKKOE,主表:EKKO-->E?专用累积,从表:EKPO-->E专用累积。
? ?
???????3、锁的生命周期
???????通常程序一运行就要对特殊记录进行ENQUEUE处理,程序运行完毕之后进行DEQUEUE处理(不显示处理的话,关闭该session的时候,sap会自动DEQUEUE,此处sap真N!)。
? ?
???????4、锁的作用范围
???????sap锁仅对特定程序起作用,假设A程序改table1的第1条记录,B程序也改table1的第1条记录,A程序一运行就对table1的第1条记录加锁,B程序则未加锁,则B程序仍可以改table1的第1条记录内容。
? ?
From <http://scnblogs.techweb.com.cn/abap/archives/6.html>
? ?
ENQUEUE_READ
2014年4月6日
23:41
? ?
这个效果SM12的操作
可以指定哪张表 哪些字段
然后看对应的记录是否被加锁
同时也可以获取一些用户在操作的记录
Exp.
SM12:
Function: Enqueue_read
? ?
Invoke:
这里实际调用方式有待商榷
直接用工厂物料?去看所有的锁
是否有哪个锁被调用
? ?
Article 3
2014年7月11日
11:46
? ?
为什么会有SAP LUW 与Lock object?
SAP系统基于三层架构, 当SAP GUI请求到达应用服务器后,分配到一个DIALOG 工作进程中,在这个进程里面DB接口可以进行OpenSQL到数据库的更新操作, 当一个屏幕处理完毕后, 会释放掉所使用的DIALOG工作进程,从而可以尽快地处理其它用户请求. 屏幕处理后会触发隐式的DB 提交,而在一个业务流程中,用户操作会跨越多个屏幕, 这样DB的LUW就不足以支持业务数据的一致性,所以SAP提供了SAP LUW以将多个操作绑定为一个逻辑单元里, 全部更新或全部取消. 而在业务操作过程中,比如修改订单时,需要对这个订单有独占性的使用, 所以对数据的访问需要有并发的控制, SAP提供了锁对象.
? ?
ABAP中的数据库更新包括两种
1> Inline update,?
???? 直接在程序中使用OpenSQL更新表内容, 或者通过PERFORM ...? ON COMMIT 来更新表内容.
2> Update module
??? 这种是通过将各个Dialog step中的数据写入到一个LOG表VBLOG中(transparent tables VBHDR, VBMOD, VBDATA, and VBERROR),然后最后一起更新到DB中去,成功后,则删除LOG表中的记录.否则,则标识失败
??? 技术实现: 通过update function module.只有IMPORTING TABLES参数,忽略EXPORTING, EXCEPTIONS
??? 在使用过程中,注意COMMIT WORK的使用, 它将会触发数据库提交更改.
??? 而使用UPDATE 函数模块时, 可以有以下几种使用方式:
??? A. 异步更新? COMMIT WORK.? 更新在UPDATE 工作进程中进行,适合对数据库较长时间操作的程序.
??? B. 同步更新? COMMIT WORK AND WAIT? 更新在另外一个工作进程中进行.
??? C. 本地更新? SET UPDATE TASK LOCAL 还是占用原来的DIALOG工作进程,但是不会写入数据到VBLOG中,避免了IO操作,速度快.适应于Batch mode.
??注意:
????? 在进行数据库更新时注意SY-SUBRC的返回值, 另外注意多个OPEN SQL更新操作是否需要在同一个LUW中, 以便处理操作失败后恢复.??
????? ?
锁概念
SAP Lock 必须在LUW期间维护, SAP Lock基于Lock object实现, 定义在DDIC中,它允许锁住一个表中的一条或多条记录或者根据外键关系锁住多个表中的记录.
有两个function: ENQUEUE_xxx and DEQUEUE_xxx用来加锁与解锁.
加锁
加锁后在Lock talbe中加入一条记录,注意Lock table存在于内存中,在整个SAP系统中只有一个,可以使用SM12来维护.
ENQUEUE_XXX主要有参数:
??? 锁类型分为三种类型的锁E独占锁,S共享锁,X
??? KEY字段
??? _scope: 定义了锁相对于LUW的持续时间, 1 程序内 2 Update module 3两者皆有.
释放锁
主要是跟加锁时的_scope有关
?? 1,需要显式调用DEQUEUE_xxx 函数??
?? 2. 至少有一个CALL FUNCTION ... FOR UPDATE TASK注册了, 并且使用COMMIT WORK时自动释放锁
?? 3. Update 与程序都需要释放锁.
注意
? DEQUEUE_ALL 这个FM,可以释放所有加的锁, 但是注意如果使用CALL FUNCTION ... FOR UPDATE TASK时, 很有可能锁被提前释放掉,所以这时最好使用COMMIT WORK.
? 还需要注意的是,加锁对性能的影响, 加锁后会影响到程序的并发性,所以加锁的时间应该尽可能的短.
? 如果使用BDC程序调用时,程序中有COMMIT WORK它会中断掉BDC的处理,此时需要在调用BDC时使用OPTIONS FROM wa选项, 设置wa的RACOMMIT为X以防止它中断.
? LUW 问题
? 向数据库中 删除数据, 插入数据, 假如插入失败,如何回退?
??? A. 显式使用ROLLBACK WORK,注意不能在PERFORM XXXX ON COMMIT. 的子程序中使用,否则会有DUMP.
??????? 也不能在 CALL FUNCTION XXXX IN UPDATE TASK的function module中使用
??? B. 有A类型消息产生.
? ?
From <http://sapjava.iteye.com/blog/505221>
? ?
SAP User Guide
2014年7月11日
_scope 参数 决定锁的释放方式
一般来说默认值是2
2 模式在 update task中 commit 或者 rollback
都会解锁!!!
(目测是这个问题导致的卧龙拣配单锁丢失)
the lock is linked to the current SAP LUW
准确的说当前LUW的提交 导致锁丢失
? ?
Setting SAP Locks
Lock function modules set or release SAP locks when called. The function locks access a central lock table in the memory of a special application server work process. Every
ABAP system contains exactly one such table (administered by transaction SM12). An enqueue function module sets an SAP lock by writing a corresponding entry in the lock table. If you cannot set a lock because corresponding lock entries already exist in the lock table, the function module terminates with the FOREIGN_LOCK exception.
The most important entry parameters of an enqueue function module are:
Parameter | Meaning |
MODE_dbtab | Type of lock for the dbtab database table of the lock object. Possible entry values include "S" for a shared lock, "E" for an exclusive lock, "X" for an expanded exclusive lock that can be requested only once unlike a regular exclusive lock within a program, and "O" for an optimistic lock which behaves like a shared lock at first, but can be converted to an exclusive lock. |
key_fields | For all key fields of the lock object, you can specify values that define the rows to be locked. If you have not specified a value for a key field, all corresponding rows are locked. |
_SCOPE | Definition of the lock duration with respect to an SAP LUW. Possible entry values include "1" for handling the lock in the same program, "2" for transferring the lock to the update, and "3" for handling the lock in the program and in the update. |
Note
You can check an SAP lock by trying to set a corresponding lock and handling the FOREIGN_LOCK exception in the process.
Releasing SAP Locks
You can release SAP locks by deleting the corresponding entry in the lock table.
When you set an SAP lock using the ENQUEUE function module, the value transferred to the _SCOPE entry parameter determines the lock duration. Depending on the formal parameter _SCOPE, you can release an SAP lock as follows:
If you want to release an SAP lock using the DEQUEUE function module independent of the update function, you must transfer a value to the formal parameter _SCOPE that is greater than or equal to the value transferred to the parameter of the same name for the ENQUEUE function module.
Besides the _SCOPE parameter, the entry parameters of a DEQUEUE function module correspond to those of the ENQUEUE function module. You can then use the additional parameter _SYNCHRON to specify whether the release of the lock should be delayed until the program processing continues.
? ?
调用 ENQUEUE/DEQUEUE 功能模块
? ?
激活锁定对 象导致系统 生成用于锁 定和解锁对 象的特殊功 能模块。这 些功能模块 称为:
ENQUEUE_<lock-object-name> ‘用于锁定 对象DEQUEUE_<lock-object-name> ‘用于解锁 对象
运行时,在 试图读或写 之前可以锁 定该数据库 对象。要锁 定对象,请 在第一屏幕 的 PAI 事件中调用 功能模块 ENQUEUE_<lock-object-name>。 要解锁此对 象,请调用 DEQUEUE_<lock-object-name>。
? ?
ENQUEUE/DEQUEUE 参数
? ?
ENQUEUE/DEQUEUE 功能模块有 下列参数集 :
? ?
?????????arg 和 x_arg????????????????( ENQUEUE 和 DEQUEUE)
? ?
这两个 EXPORTING 参数,存在 于锁定参数 的每个字段 arg 中。将 arg 设置为所需 的关键字字 段值。如果 该字段不需 要特殊值, 则忽略 arg
参数,或者 将其设置为 字段的初始 值。如果要 将字段的初 始值作为实 际选择值, 请将 x_arg 设置为‘X‘ 。
? ?
?????????_SCOPE????????????????(ENQUEUE)
? ?
如果事务不 调用更新任 务功能,则 只在对话任 务中更新。 应该使用相 应的 DEQUEUE 功能直接释 放锁定。
如果调用任 意的 V1 更新任务功 能,请设置 参数 _SCOPE 以告知系统 应该如何释 放 SAP 锁定。可能 的值为:
? ?
1????????该值用 于创建更新 任务中不需 要的锁定。 在整个对话 任务处理中 保持使用 _SCOPE=1 设置的锁定 ,但该锁定 并不能用于 任意的更新 任务请求。 要保证不将 锁定保持超 过必要的时 间,在事务 结束时应该 直接释放它 (通过相应 的DEQUEUE 功能)。
在ROLLBACK WORK 时释放:系 统不释放使 用 _SCOPE=1 设置的锁定 。在编制反 转程序时, 请使用 DEQUEUE 功能。
? ?
2????????该值用 于创建下列 锁定:
? ?
-????????在更新 任务触发之 前在对话任 务中使用
-????????一旦已 经触发了更 新任务,则 只在更新任 务中使用。
这意味着在 COMMIT WORK 已经触发更 新任务之后 ,如果该任 务继续运行 ,则锁定不 再可用于对 话任务事务 。系统在 V1 更新任务处
理结束之后 (或者在下 一 ROLLBACK WORK) 释放锁定。
如果不指定 _SCOPE, 该值就是缺 省值。不需 要将DEQUEUE 用于 使用 _SCOPE 值创建的锁 定。但是, 如果 _SCOPE = 2,并且不 调用更新任 务功能,则 不触发更新 任务而且系 统不释放锁 定。
? ?
在 ROLLBACK WORK 释放:如果 在提交前发 生反转,则 系统释放使 用 _SCOPE=2 设置的锁定 。在提交之 后 ,锁定保持 到更新任务
处理结束。
3????????使用该 值创建以下 锁定:
? ?
-????????在触发 更新任务之 前在对话任 务中使用
-????????在触发 更新任务之 后,由对话 任务和更新 任务使用。
也就是说, 对话任务程 序继续使用 该锁定,甚 至该更新任 务功能正在 运行时也是 如此。在这 种情况下, 锁定由对话 事务和更新 任务功能所 "共有"。
在 V1 更新任务处 理之后的某 个时刻系统 释放锁定。 但是,应该 直接释放锁 定(通过相 应的 DEQUEUE 函数)以确 保尽可能早 地释放。
? ?
在 ROLLBACK WORK 释放:一旦 已经触发更 新任务,则 使用 _SCOPE=3 设置的锁定 有两个独立 的所有者。 要删除锁定 ,必须在对
话任务和更 新任务两方 同时删除此 锁定。如果 在提交前发 生反转,则 在更新任务 方释放锁定 ,但是对话 任务方仍然 保留它。如 果在提交后 发生反转, 则系统在双 方都不释放 该锁定。在 这种情况下 ,必须使用 DEQUEUE 功能在对话 方直接释放 该锁定。更 新任务方将 自动释放锁 定。
? ?
如果用户在 事务完成前 已经退出了 该事务(例 如通过"/n" )或者程序 异常终止, 则系统释放 所有锁定。 V2 功能也不能 继承对话任 务所创建的 锁定。
? ?
?????????_WAIT????????????????????????( 只 ENQUEUE)
? ?
此 EXPORTING 参数告知: 如果即将锁 定的对象已 经由其它用 户锁定,ENQUEUE 是否应该等 待。如果要 等待则将 _WAIT 设置为 ‘X‘。在
这种情况下 ,系统试图 以指定时间 长度的重复 间隔锁定该 对象。如果 这些尝试失 败,则 ENQUEUE 导致 FOREIGN_LOCK 例外。
如果程序不 想等待,则 将 _WAIT 设置为其它 任何值。在 这种情况下 ,ENQUEUE 导致 FOREIGN_LOCK 例外,并且 将系统字段 SY-MSGV1
设置为已经 拥有该锁定 的用户名。
? ?
ENQUEUE 例外
? ?
在调用 ENQUEUE 功能模块之 后,应该检 查在程序中 该对象是否 已经锁定。 在功能模块 中定义了下 列例外:
? ?
?????????FOREIGN_LOCK
? ?
其它用户已 经锁定了对 象。系统字 段 SY_MSGV1 包含该用户 名。
? ?
?????????SYSTEM_FAILURE
? ?
一般系统错 误。
? ?
Neither this documentation nor any part of it may be copied or reproduced in any form or by any means or translated into another language, without the prior consent of SAP AG.
? ?
Input parameters
2014年7月11日
16:19
? ?
Input parameters for?ENQUEUE/DEQUEUE Functions . - SAP Lock Mechanism -
A closer look at the lock FM parameters which is used commonly by transactional processes.
****************************************************
X_
A further parameter X_ that defines the lock behavior when the initial value is passed exists for every lock field . If the initial value is assigned to and X_, then a generic lock is initialized with respect to . If is assigned the initial value and X_ is defined as X, the lock is set with exactly the initial value of .
Well , this means if you need a parameters initial value to lock , you must set X_ = ‘X‘ for this purpose otherwise it locks entire values.
_SCOPE
1: Locks or lock releases are not passed to the update program. The lock is removed when the transaction is ended.
2: The lock or lock release is passed to the update program. The update program is responsible for removing the lock. The interactive program with which the lock was requested no longer has an influence on the lock behavior. This is the standard setting for the?ENQUEUE?function module.
3: The lock or lock release is also passed to the update program. The lock must be removed in both the interactive program and in the update program. This is the standard setting for the DEQUEUE function module.
Meaning of the?_SCOPE?Values
Value | Description |
_SCOPE?= 1 | The lock belongs only to the dialog owner (owner_1), and therefore only exists in the dialog transaction. The?DEQUEUE?call or the end of the transaction, notCOMMIT WORK?or?ROLLBACK WORK,?cancels the lock. |
_SCOPE?= 2 | The lock belongs to the update owner (owner_2) only. Therefore, the update inherits the lock whenCALL FUNCTION ‘…‘ IN UPDATE TASK?and?COMMIT WORK?are called.?The lock is released when the update transaction is complete. You can release the lock before it is transferred to the update usingROLLBACK WORK.?COMMIT WORKhas no effect, unless?CALL FUNCTION ‘…‘ IN UPDATE TASK?has been called. |
_SCOPE?= 3 | The lock belongs to both owners (owner_1 and owner_2). In other words, it combines the behavior of both. This lock is canceled when the last of the two owners has released it. |
? ?
MODE_
S (read lock)?
E (write lock)?
X (extended write lock)
O (optimistic lock)
Locks Modes
Type of Lock | Lock mode | Description |
Shared lock | S?(Shared) | Several users (transactions) can access locked data at the same time in display mode. Requests from further shared locks are accepted, even if they are from different users. An exclusive lock set on an object that already has a shared lock will be rejected. |
Exclusive lock | E?(Exclusive) | An exclusive lock protects the locked object against all types of locks from other transactions. Only the same lock owner can reset the lock (accumulate). |
Exclusive but not cumulative lock | X?(eXclusive non-cumulative) | Whereas exclusive locks can be requested several times by the same transaction and released one by one, an exclusive, non-cumulative lock can only be requested once by the same transaction. Each further lock request will be rejected. |
Optimistic lock | O(Optimistic) | Optimistic locks initially behave like shared locks and can be converted into exclusive locks. SeeOptimistic Locks. |
_COLLECT
Initial Value: The lock request or lock release is sent directly to the lock server.
X: The lock request or lock release is placed in the local lock container. The lock requests and lock releases collected in this lock container can then be sent to the lock server at a later time as a group by calling the function module FLUSH_ENQUEUE.
_WAIT
Initial Value: If a lock attempt fails because there is a competing lock, the exception FOREIGN_LOCK is triggered.
X: If a lock attempt fails because there is a competing lock, the lock attempt is repeated after waiting for a certain time. The exception FOREIGN_LOCK is triggered only if a certain time limit has elapsed since the first lock attempt. The waiting time and the time limit are defined by profile parameters.
_SYNCHRON
If X is passed, the DEQUEUE function waits until the entry has been removed from the lock table. Otherwise it is deleted asynchronously, that is, if the lock table of the system is read directly after the lock is removed, the entry in the lock table may still exist.
Exceptions of the?ENQUEUEFunction Module
FOREIGN_LOCK: A competing lock already exists. You can find out the name of the user holding the lock by looking at system variable SY-MSGV1.
SYSTEM_FAILURE: This exception is triggered when the lock server reports that a problem occurred while setting the lock. In this case, the lock could not be set.
? ?
? ?
BAPI test_run导致的锁定
2014年12月23日
14:53
某些bapi中提供test_run的参数
bapi中如果存在锁定
Test_run也会进行锁定
? ?
并且不会被释放
(通常在bapi提交的时候会释放锁定)
标签:
原文地址:http://www.cnblogs.com/rootbin/p/4463507.html