Tag Archives: ABAP

[repost ]关于SAP Lock (二)

original:http://scnblogs.techweb.com.cn/tcsapbw/archives/1788.html

在前面【Lock】关于Lock后,有朋友问到:我已经了解到了SAP Lock的机制原理了,现在该如何创建Lock object,貌似在调用Enqueue FM时可以omit一些parameter,既可以在SE11创建Lock-object时omit一些key-field也可以在调用FM时omit一些lock parameter?

这里,因为Lock在SAP中使用非常的广泛,也是最基本的一个应用之一.所以这里再做一个总结,继续补充SAP Lock.本篇将主要讨论在Lock中Generic(通用)的应用以及Lock secondary table.

关于Lock,也许平常,我们使用最多的就是:

在se11中创建锁对象:指定锁对象table的锁定Key field组合; 

然后在程序中,完全指定了锁对象的key fields组合。

然而,有时候我们却需要利用现存的锁对象,但我们不一定需要将所有的key field都指定上,这时候Lock的Generic特性就体现出来了。

1.一般性的Generic实例

使用数据库表SBOOK,其结构如下:

 

创建Lock Object 1: EZ_SBOOK_1

 

(注意,这里lock mode应为X,便于后文进行Lock的Generic的累加测试)

其中Lock Parameter:

 

(这里将MANDT去掉,与下面第二部分进行对比)

然后,我们来看一下SBOOK中的数据:

 

好,程序中使用Lock

ZTEST_LOCK_5:

*&———————————————————————*

*& Report  ZTEST_LOCK_5                                                *

*&                                                                     *

*&———————————————————————*

*&  Using Lock – Generic Lock                                          *

*&                                                                     *

*&———————————————————————*

 

REPORT  ZTEST_LOCK_5  no  standard page heading         .

 

*—Data and Types

data:

ls_zbook  type sbook.

 

 

start-of-selection.

 

*—1st Time Lock

**Only Lock Argument: Carrid = ‘AA’ Connid = ‘0017′

write:/ ‘1st Time Lock:’,

20 ‘Only Lock Argument: Carrid = ”AA” Connid = ”0017”’.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘AA’

CONNID               = ‘0017′

*   FLDATE               =

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

*—2nd Time Lock

**Lock attempt: Carrid = ‘AA’ Connid = ‘0017′ FLDATE = ‘06.03.2002′

write:/ ‘2nd Time Lock:’,

20 ‘Lock attempt: Carrid = ”AA” Connid = ”0017” FLDATE = ”06.03.2002”’.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘AA’

CONNID               = ‘0017′

FLDATE               = ‘06032002′

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

*—3rd Time Lock

**Lock attempt: Carrid = ‘AA’

write:/ ‘3rd Time Lock:’,

20 ‘Lock attempt: Carrid = ”AA” ‘.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘AA’

*   CONNID               =

*   FLDATE               =

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

最后执行

 

可以发现,后面两次lock(一次是小范围,一次是大范围)都Lock失败

(疑问:也许您会说,因为锁类型为X嘛,所以在同一个program中不可累加,所以后两次是失败的;Okay,先不论它们锁的对象是否相同,咱们再来做另外两个程序分program地进行测试)

ZTEST_LOCK_6:

*&———————————————————————*

*& Report  ZTEST_LOCK_6                                               *

*&                                                                     *

*&———————————————————————*

*&  Using Lock – Generic Lock                                          *

*&                                                                     *

*&———————————————————————*

 

REPORT  ZTEST_LOCK_6  no  standard page heading         .

 

*—Data and Types

data:

ls_zbook  type sbook.

 

 

start-of-selection.

*—2nd Time Lock

**Lock attempt: Carrid = ‘AA’ Connid = ‘0017′ FLDATE = ‘06.03.2002′

write:/ ‘2nd Time Lock:’,

20 ‘Lock attempt: Carrid = ”AA” Connid = ”0017” FLDATE = ”06.03.2002”’.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘AA’

CONNID               = ‘0017′

FLDATE               = ‘06032002′

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

当上面Lock 5保持运行状态,执行后:

 

同时ZTEST_LOCK_7:

 

*&———————————————————————*

*& Report  ZTEST_LOCK_7                                                *

*&                                                                     *

*&———————————————————————*

*&  Using Lock – Generic Lock                                          *

*&                                                                     *

*&———————————————————————*

 

REPORT  ZTEST_LOCK_7  no  standard page heading         .

 

*—Data and Types

data:

ls_zbook  type sbook.

 

 

start-of-selection.

*—3rd Time Lock

**Lock attempt: Carrid = ‘AA’

write:/ ‘3rd Time Lock:’,

20 ‘Lock attempt: Carrid = ”AA” ‘.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘AA’

*   CONNID               =

*   FLDATE               =

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

当上面Lock 5保持运行状态,执行后:

 

但是,如果我们锁“没有发生冲突”的对象(无论是指定的一条,还是有Generic);如下测试程序:

ZTEST_LOCK_8:

*&———————————————————————*

*& Report  ZTEST_LOCK_8                                               *

*&                                                                     *

*&———————————————————————*

*&  Using Lock – Generic Lock                                          *

*&                                                                     *

*&———————————————————————*

 

REPORT  ZTEST_LOCK_8  no  standard page heading         .

 

*—Data and Types

data:

ls_zbook  type sbook.

 

 

start-of-selection.

*—4th time Lock

**Lock attempt: Carrid = ‘BB’

write:/ ‘4th Time Lock:’,

20 ‘Lock attempt: Carrid = ”BB” ‘.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘BB’

*   CONNID               =

*   FLDATE               =

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

当上面Lock 5保持运行状态,执行后:

 

SM12锁对象:

 

(前面两条可以不用考虑)可以发现,我们的锁对象的Lock Argument中使用了#的Generic;

可以得出结论:

无论是unique指定一条还是使用了Generic,如果有冲突就会lock 失败.

另外,如果未将client作为lock parameter,但其锁定还是generic;

2.有client的generic实例

继续接上;

现在新建一lock object2,不同于lock object1它带上了Client;

它对表SFLIGHT进行加锁,如下:

 

我们先来看一下SFLIGHT这张表的all client数据(见前面的client specific一章)

 

测试程序:

*&———————————————————————*

*& Report  ZTEST_LOCK_9                                                *

*&                                                                     *

*&———————————————————————*

*&  Using Lock – Generic Lock                                          *

*&                                                                     *

*&———————————————————————*

 

REPORT  ZTEST_LOCK_9  no  standard page heading         .

 

start-of-selection.

*—1st Time Lock

**Lock attempt: MANDT = space Carrid = ‘LH’

write:/ ‘1st Time Lock:’,

20 ‘Lock attempt: MANDT = space Carrid = ”LH” ‘.

CALL FUNCTION ‘ENQUEUE_EZ_SFLIGHT_1′

EXPORTING

MODE_SFLIGHT         = ‘X’

MANDT                = ‘ ‘

CARRID               = ‘LH’

*   CONNID               =

*   FLDATE               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

 

*—2nd Time Lock

**Lock Argument: MANDT(omit) Carrid = ‘AA’

write:/ ‘2nd Time Lock:’,

20 ‘Lock Argument: MANDT(omit) Carrid = ”AA” ‘.

CALL FUNCTION ‘ENQUEUE_EZ_SFLIGHT_1′

EXPORTING

MODE_SFLIGHT         = ‘X’

*   MANDT                =

CARRID               = ‘LH’

*   CONNID               =

*   FLDATE               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

*—3rd Time Lock

**Lock attempt: MANDT = 810  Carrid = ‘LH’

write:/ ‘3rd Time Lock:’,

20 ‘Lock attempt: MANDT = 810 arrid = ”LH” ‘.

CALL FUNCTION ‘ENQUEUE_EZ_SFLIGHT_1′

EXPORTING

MODE_SFLIGHT         = ‘X’

MANDT                = ‘810′

CARRID               = ‘LH’

*   CONNID               =

*   FLDATE               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

这里执行效果为:

 

此时SM12中锁对象将为:

 

如果将上面的第一次与第二次还处顺序则结果为:

 

此时SM12中锁对象将为:

 

3.关于Lock Paramert中Generic Argument的结论

综上第一部分与第二部分的2个测试,我们可以得出以下结论:

(1) Lock Argument是跟着锁定对象的table走的,它有多少个key field,那么我们的锁对象就会包含”真正”的多少个parameter;但我们可以在创建锁对象时省略掉自己业务上不需要的parameter,但这里的省略是指在call 加锁FM时没有这个import参数而已;在实际的锁中,它是以Generic的形式存在着; 

(2) Generic这是一个通用的参数;就像我们不能对一条相同的数据加两次锁(注意不是S也不是一个program中的多次E)一样,如果在进地加锁时,发生了”冲突”,那么加锁是不成功的。

(3) 对于Client这个参数比较特殊:

* 如果lock parameter中将client排除了,那么其lock针对所有client,是generic的(前面总结第一条也说);

* 如果lock parameter中包含client,同时 client的parameter没有被指定(也就是Omit掉了),那么lock 只针对当前的client record进行

* 如果lock parameter中包含client,同时client的parameter指定了,那么lock就针对指定的client record进行

* 如果lock parameter中包含client,同时client的parameter指定为space,那么lock针对所有的client的record进行

4.关于Lock的主表与从表

这里再记录一下另一个经常使用到的Lock机能,那就是Lock中设置Secondary Tables.如下:

 

这个锁对象表明主锁是对表sflight进行X锁定,同时,根据外键锁定SBOOK中的相应记录;

当创建主锁时,会将外键作为一个Generic进行同时上附加/secondary锁;

这里,特别要注意的是,二者的表必须是要用外键关系;

如上,使用上面分别创建的两个锁对象,测试程序:

*&———————————————————————*

*& Report  ZTEST_LOCK_10                                               *

*&                                                                     *

*&———————————————————————*

*&  Using Lock – Generic Lock                                          *

*&                                                                     *

*&———————————————————————*

 

REPORT  ZTEST_LOCK_10  no  standard page heading  .

 

start-of-selection.

 

*—1st Time Lock

**Lock attempt: Sflight

write:/ ‘1st Time Lock:’,

20 ‘Lock attempt: Sflight’.

CALL FUNCTION ‘ENQUEUE_EZ_SFLIGHT_1′

EXPORTING

MODE_SFLIGHT         = ‘X’

*   MANDT                =

CARRID               = ‘AA’

CONNID               = ‘0017′

FLDATE               = ‘06032002′

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

 

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

Uline /(80).

 

*—2nd Time Lock

**Lock attempt: sbook

write:/ ‘2nd Time Lock:’,

20 ‘Lock attempt: sbook’.

CALL FUNCTION ‘ENQUEUE_EZ_SBOOK_1′

EXPORTING

MODE_SBOOK           = ‘X’

CARRID               = ‘AA’

CONNID               = ‘0017′

FLDATE               = ‘06032002′

*   BOOKID               =

*   X_CARRID             = ‘ ‘

*   X_CONNID             = ‘ ‘

*   X_FLDATE             = ‘ ‘

*   X_BOOKID             = ‘ ‘

_SCOPE               = ‘2′

_WAIT                = ‘ ‘

_COLLECT             = ‘ ‘

EXCEPTIONS

FOREIGN_LOCK         = 1

SYSTEM_FAILURE       = 2

OTHERS               = 3

.

IF SY-SUBRC <> 0.

write:/ ‘Lock Failed!’.

ELSE.

write:/ ‘Lock Successed!’.

ENDIF.

 

执行结果

 

此时SM12中查看锁对象

 

可以发现:当在上主锁时,会对从表也进行加锁(外键以Generic对待)。

 

TIOBE Programming Community Index for November 2010,First cracks appear for Objective-C

November Headline: First cracks appear for Objective-C

After having been the rising star for a long time now, Objective-C dropped considerably last month. The ratings for Objective-C are 0.5% less if compared to October. Other remarkable changes in the TIOBE index this month are the first time entrance of Lego’s Mindstorms programming language NXT-G in the top 20, the sudden decline of Google’s Go (out of the top 20) and the lowest position for Visual Basic ever since the start of the index.

The TIOBE Programming Community index is an indicator of the popularity of programming languages. The index is updated once a month. The ratings are based on the number of skilled engineers world-wide, courses and third party vendors. The popular search engines Google, MSN, Yahoo!, Wikipedia and YouTube are used to calculate the ratings. Observe that the TIOBE index is not about the best programming language or the language in which most lines of code have been written.

The index can be used to check whether your programming skills are still up to date or to make a strategic decision about what programming language should be adopted when starting to build a new software system. The definition of the TIOBE index can be found here.

Position
Nov 2010
Position
Nov 2009
Delta in Position Programming Language Ratings
Nov 2010
Delta
Nov 2009
Status
1 1 Java 18.509% +0.14% A
2 2 C 16.717% -0.60% A
3 4 C++ 9.497% -0.50% A
4 3 PHP 7.813% -2.36% A
5 6 C# 5.706% +0.36% A
6 7 Python 5.679% +1.01% A
7 5 (Visual) Basic 5.470% -2.70% A
8 13 Objective-C 3.191% +2.30% A
9 8 Perl 2.472% -1.02% A
10 10 Ruby 1.907% -0.50% A
11 9 JavaScript 1.664% -1.25% A
12 11 Delphi 1.638% -0.49% A
13 17 Lisp 1.087% +0.47% A
14 23 Transact-SQL 0.793% +0.38% A
15 15 Pascal 0.784% +0.13% A
16 29 Ada 0.695% +0.39% B
17 36 NXT-G 0.682% +0.45% B
18 14 SAS 0.669% -0.15% B
19 30 RPG (OS/400) 0.656% +0.37% B
20 12 PL/SQL 0.655% -0.25% B

Long term trends

The long term trends for the top 10 programming languages can be found in the line diagram below.


Other programming languages

The complete top 50 of programming languages is listed below. This overview is published unofficially, because it could be the case that we missed a language. If you have the impression there is a programming language lacking, please notify us at tpci@tiobe.com.

Position Programming Language Ratings
21 MATLAB 0.636%
22 Lua 0.612%
23 ABAP 0.597%
24 Object Pascal 0.556%
25 Go 0.548%
26 Scheme 0.508%
27 Fortran 0.477%
28 Tcl 0.423%
29 D 0.414%
30 COBOL 0.405%
31 Logo 0.397%
32 CL (OS/400) 0.371%
33 APL 0.366%
34 JavaFX Script 0.366%
35 R 0.365%
36 JScript.NET 0.330%
37 C shell 0.327%
38 ActionScript 0.326%
39 Scratch 0.325%
40 IDL 0.325%
41 Visual Basic .NET 0.323%
42 Haskell 0.312%
43 Alice 0.311%
44 Prolog 0.300%
45 Erlang 0.267%
46 Smalltalk 0.266%
47 Forth 0.256%
48 Awk 0.238%
49 ML 0.237%
50 Scala 0.235%

The Next 50 Programming Languages

The following list of languages denotes #51 to #100. Since the differences are relatively small, the programming languages are only listed (in alphabetical order).

  • ABC, Algol, Applescript, Bash, bc, Beta, C++/CLI, CFML, cg, Clean, Clipper, Cobra, cT, Curl, Dylan, Eiffel, Euphoria, F#, Factor, Groovy, Icon, Io, J, LabVIEW, LabWindows/CVI, MAD, MAX/MSP, Modula-2, Modula-3, MUMPS, Natural, Oberon, Objective Caml, Occam, Oz, PL/I, Postscript, PowerShell, Q, REALbasic, S, SIGNAL, SPSS, Squirrel, Standard ML, Verilog, VHDL, XBase, XSLT, Z shell

Very Long Term History

To see the bigger picture, please find the positions of the top 10 programming languages from 5, 15 and 25 years ago in the table below.

Programming Language Position
Nov 2010
Position
Nov 2005
Position
Nov 1995
Position
Nov 1985
Java 1 1
C 2 2 1 1
C++ 3 3 2 8
PHP 4 4
C# 5 7
Python 6 8 10
(Visual) Basic 7 5 3 4
Objective-C 8 42
Perl 9 6 5
Ruby 10 24
Lisp 13 14 12 2
Ada 16 17 6 3

Programming Language Hall of Fame

The hall of fame listing all “Programming Language of the Year” award winners is shown below. The award is given to the programming language that has the highest rise in ratings in a year.

Year Winner
2009 Go
2008 C
2007 Python
2006 Ruby
2005 Java
2004 PHP
2003 C++

Categories of Programming Languages

In the tables below some long term trends are listed about categories of languages. Object-oriented statically typed languages are most popular now for more than 4 years.

Category Ratings Nov 2010 Delta Nov 2009
Object-Oriented Languages 56.7% +2.4%
Procedural Languages 38.0% -3.5%
Functional Languages 3.6% +0.7%
Logical Languages 1.7% +0.4%
Category Ratings Nov 2010 Delta Nov 2009
Statically Typed Languages 63.1% +4.1%
Dynamically Typed Languages 36.9% -4.1%