Non-reentrant locking

Hi,
I am trying to prevent someone from submitting the same information twice in quick succession on my Tomcat web application before the first submit action has completed.
Here is basically what my code looks like now:
String email = getEmailAddressOfSubmitter();
synchronized (email) {
// Process data that has been submitted
// This processing needs to finish completely before
// this block is executed again for this same email
This is preventing other threads from entering this synchronized block until it has completed, but it looks to me like the same thread entering this method again with another request is allowed to go through, because the thread already has the lock on this email address object.
This is causing data to be saved twice because in the short time between when I check if a record already exists in the database and when a new one has been saved another request sneeks in and also saves a record.
How can I prevent the same thread from entering this block again with another request until processing has finished for this email?
I suspect it has something to do with non-reentrant locking, but I don't understand a word of what I've read about it so far.
Thanks in advance,
Evert

I don't know if this is the problem with your
program, but what you describe is possible: in Java
(differing from POSIX threads) a thread can access a
single lock (a synchronized method) more than once.
It's called reentrant locking.I assume that in practice this can really just happen if I have a method that calls itself. In my case with a web application, I assume the thread would complete one request completely before starting with the next http request. Other threads might interject, but the same thread should finish one request before starting the next.
I've done what BinaryDigit suggested and synchronized on email.intern() instead of just on email, and it looks like that did the trick. After 6 years of Java programming, I've forgotten that two strings are not necessarily == when they are equal. It's time for me to grab my beginner Java books again!

Similar Messages

  • Reentrant lock with Orchestra conversation scoped bean on second AJax call

    I'm just trying to set us a fairly straightforward JSF 2.0 / Spring / PrimeFaces application. Since backing bean expiry has been such a nuisance I thought I'd give Orchestra's conversation scope mechaniism a go.
    the problem I'm getting seems to occur on the second Ajax transaction for the page.
    WARNING: Waited for longer than 30000 milliseconds for access to lock org.apache.myfaces.orchestra.lib._ReentrantLock@2e8da6a9 which is locked by thread http-8084-5
    22-Mar-2011 11:16:13 org.apache.myfaces.orchestra.lib._ReentrantLock lockInterruptiblyThis message repeats, and the Ajax transaction never returns.
    I know that Orchestra locks the coversation scoped beans during the processing of a transaction to avoid threading issues (since they may contain non-reentrant objects like EntityMangers etc.) I'm assuming that, somehow, the backing bean is not unlocked at the end of the first Ajax transaction. But the configuration of listeners etc. should be being done automatically.
    Anyone tried a combination like this?

    never even heard of it. If I'd need a conversation scope (and I rarely do), I'd go for Seam 3 in stead even if it is not final yet.

  • (V8.1.7) OPS : PCM LOCK과 NON-PCM LOCK에 대한 정리

    제품 : ORACLE SERVER
    작성날짜 : 2004-08-13
    (V7.3 ~ V8.1.7) OPS : PCM LOCK과 NON-PCM LOCK에 대한 정리
    =========================================================
    PURPOSE
    OPS 환경에서는 single instance와는 구별되어 PCM lock이라는 것이 존재한다.
    이것이 Non-PCM Lock과 어떻게 다르며, 어떤 방식으로 할당되는지에 대하여
    Oracle 8i(8.1.7) 버젼을 기준으로, 관련된 GC_* 파라미터에 대한 설명과 함
    께 소개하고자 한다.
    오라클 OPS 환경에서는 PCM lock 관련 파라미터를 어떻게 설정하느냐에 따라
    system 전체의 성능에 많은 영향을 미친다.
    SCOPE
    Oracle Parallel Server(OPS) Option은 8~9i Standard Edition에서는
    지원하지 않는다.
    Explanation
    1. Instance Lock
    Instance Lock에는 PCM Lock과 Non-PCM Lock 두가지가 존재한다.
    PCM(Parallel Cache Management) Lock은 Buffer cache 내의 block의 lock
    에 관련된 부분이고, Non-PCM Lock은 그 이외의 Lock이다.
    Non-PCM Lock에는 DFS enqueue lock과 DFS Lock 두가지가 있다.
    Instance Lock은 동기화에 필요한 cost가 굉장히 높으며, OPS 환경에서는
    PCM Lock의 갯수가 Non-PCM Lock의 갯수보다 훨씬 많다.
    이 PCM Lock의 갯수를 적절하게 잘 설정해야만 DLM을 적절하게 잘 구성했
    다 라고 말할 수 있다.
    2. PCM Lock
    1) PCM Lock은 X$LE 또는 GV$LOCK_ELEMENT 내에 기술된 lock element
    block class에 internal하게 mapping된다.
    2) lock element라고 불리우는 data structure 내에 state 정보를 저장한다.
    3) 다음과 같이 두 가지 방법으로 구현된다.
    1:1 or 1:n releasable locks
    1:1 or 1:n fixed locks
    3. Fixed Locking
    1) Oracle7에서는 default로 fixed locking 방법을 사용한다.
    2) DBA(data block address)에 hashing 알고리즘을 적용하여 data file
    block에 instance lock을 할당한다.
    3) Fixed locking 기법은 instance startup 시에 block에 hash 알고리즘
    을 이용하여 정적으로 할당이 된다.
    4) Fixed locking 기법은 보통 여러개의 data block을 cover한다.
    각 data file마다 고정된 수의 PCM lock이 할당되고, 한 datafile 당
    block 수가 몇 개인가에 따라 한 PCM lock이 관할하는 data block의 수
    가 결정이 된다.
    4. GC_FILES_TO_LOCKS
    각 datafile 당 PCM Lock의 갯수를 정하기 위하여 위 파라미터를
    initSID.ora 화일에 셋팅한다. 만약, 이 파라미터가 지정되어 있지 않으
    면, Oracle 7에서는 hashing 알고리즘에 근거하여 fixed하게 lock이
    assign되지만, Oracle 8부터는 releasable lock이 사용된다.
    해당 instance의 총 lock의 갯수를 지정하는 GC_DB_LOCKS 파라미터는
    Oracle 8부터 없어졌다.
    GC_FILES_TO_LOCKS = "{file_list=lock_count[!blocks][R][each]}:..."
    syntax는 위와 같다. 아래에 각각에 대한 설명을 추가한다.
    file_list : datafile 하나 또는 여러개를 set으로 지정 가능
    lock_count : file_list에 나타난 datafile에 대한 PCM lock의 갯수
    !blocks : cover할 연속된 block의 갯수
    R : 지정한 lock에 대해서는 releasable하다는 의미
    each : file_list에 지정한 각 datafile에 대해 할당된 lock의 갯수
    Example
    1=1000!25R
    1-3=500EACH
    1=300:2=100
    5. Instance Lock : FILE_LOCK view
    Oracle 7.3부터 제공되는 view로서 각 datafile에 대하여 PCM Lock이 얼마
    나 많이 할당되었는지 확인하는 view이다.
    select file_id, file_name, ts_name, start_lk, nlocks, blocking
    from file_lock;
    file_id : datafile number
    file_name : datafile name
    ts_name : tablespace name the file belongs to
    start_lk : first lock corresponding to the datafile
    nlocks : number of PCM locks allocated to the datafile
    blocking : number of blocks protected by a PCM lock on the file
    6. 1:1 Releasable Locking
    1) 1:1 releasable locking이 Oracle 8부터는 default이다.
    2) Releasable locking은 dynamic하게 PCM lock을 block에 assign한다.
    3) Lock은 필요할 때 assign되고 release된다.
    4) Block이 release되고 나면 PCM lock 또한 release된다.
    5) Lock element name은 Lock element가 reuse될 때마다 변한다.
    6) Instance startup하는 데 걸리는 시간이 더 빠르다. 그러나, request
    시에 DLM resource를 allocate하는 데 요구되는 시간이 더 많이 든다.
    7. Non-PCM Locks
    1) Non-PCM Lock은 dynamic하게 할당되고, PCM lock에 비해서 그 갯수는
    훨씬 적다. (시스템 전체 Lock의 5 ~ 10% 에 불과)
    2) Non-PCM Lock의 갯수를 직접 조절할 수 있는 초기화 파라미터는 없다.
    (except DML_LOCKS)
    3) Non-PCM Lock은 data block을 protect하지는 않는다. 그것은 PCM Lock
    의 job이다.
    4) 다음과 같은 역할을 하는 많은 type의 Non-PCM Lock이 있다.
    - Control access to data and control files
    - Control library and dictionary caches
    - Provide communication between instances
    5) Non-PCM Lock의 space를 조절하는 parameter들.
    DB_BLOCK_BUFFERS, DB_FILES, DML_LOCKS, PARALLEL_MAX_SERVERS,
    PROCESSES, SESSIONS, TRANSACTIONS
    6) DML_LOCKS = 0 으로 설정하고 운영하는 것이 OPS에서는 일반적이다.
    OPS에서는 block level lock이 우선이므로, table lock이 자주 걸리는
    것이 바람직하지 않다. CREATE 또는 ALTER와 같은 작업을 할 경우에만
    이 파라미터 값을 0이 아닌 다른 값으로 설정하고, 그렇지 않은 경우에
    는 두 instance 모두 0으로 설정한다. 두 instance 모두 같은 값이어
    야 할 필요는 없으나, 0으로 설정할 경우에는 양쪽 모두 0으로 설정해
    야 한다.
    8. PCM Lock을 할당하기 위한 몇 가지 tips
    1) Always set GC_FILES_TO_LOCKS
    2) The value for GC_FILES_TO_LOCKS must be the same on all instances
    3) Do not assign locks to undo segment files
    4) No locks needed for temporary/sort blocks
    5) Group read-only objects together and allocate 1 hashed lock to
    the file
    6) Make tablespaces read-only, (no PCM locks used)
    7) Never assign DBA locking to read-only or mostly read only data
    8) If excessive pinging on undo blocks (down converts: X->SSX),
    increase GC_ROLLBACK_LOCKS
    Example
    none
    Reference Documents
    <Note:30508.1>
    <Note:50244.1>
    OPS 8i Administrator Guide.

  • Non-Reentr​ant VI executing in different Process Stacks

    I am creating a DLL which can be called by several different processes on a machine at the same time. If I have a non-reentrant VI in the API, do the same restrictions apply between processes as if they were in the same process? For example, if I call "Get Shorty.vi" which is a non-reentrant VI from 2 places in the same process, at the same time, the first call will start executing, and the second call will wait till the first call is done. When called from 2 different process stacks, there is supposed to be total seperation of memory windows, so logic tells me that this restriction would not apply if that same VI were called from 2 different processes.
    The catch is that the VI Library installed by the run-time engine is used by both processes as well. Would this, in effect, cause the same behavior between 2 calls to the same VI both in process and out?
    Thanks for any help you can provide. This is not a easy to describe concept, so feel free to ask for clarification if needed.
    CyberTazer
    Software Systems Engineer

    I understand that the memory spaces are supposed to be completly seperate. The question is that if 2 processes call the same function in the same dll at the same time... will one process have to wait on the other process to finish before being allowed to execute? My feeling on this is no, it would not have to wait, but I am hoping that someone out there has a more difinitive answer.
    There is no shared memory mechanisms set up in this vi.. ie for persistant data between execution processes. I am not even sure if this is possible with LV dll's, but I thought I would throw that in there since I know it is possible in general.
    Thanks again for your help guys... keep em comming. Hopefully this will help clear up other peoples perceptions on how dll execution is handled in LV if we can nail this down a bit more.
    CyberTazer
    Software Systems Engineer

  • Reentrant locks and exec()

    I'm trying to run Linux system commands on locked resources in the context of a p2p distributed system. As persons in this forum probably know probably better than I do, this is remarkably difficult. I've tried a variety of different approaches and languages. My latest stab is doing it with Java and the Hazelcast system as the distributed lock manager. Supposedly Hazelcast's distributed locks work the same way as Java's "regular" reentrant locks and so I'm trying to understand exactly what will happen with those under different failure modes. For example, say I have some code that roughly looks like this:
    private final ReentrantLock lock = new ReentrantLock();
    public void m() {
         lock.lock();  // block until condition holds
         try {
                   Process p = Runtime.getRuntime().exec("some system command that will take a long time");
        } finally {
           lock.unlock()
    }Am I correct that the parent process could lose the lock or otherwise fail while the process that runs the system command is oblivious and keeps happily running anyway? Is there some easy way to guard against that? Thanks for any insight!

    Runtime.exec() returns immediately and the lock will be released right after exec(), so yes, the system command will keep running anyway. Probably what you need to to is to wait until the spawned process finishes ( Process.waitFor() )

  • Recursive reference in non-reentrant vi

    I've upgraded to LabView 2012 from 2011 and when I open a VI saved in 2011 each of the DAQ Assistants shows the error "recursive reference in non-reentrant VI". The help menu says to click the "reentrant execution" checkbox in my VI propertires pull down menu but I can't seem to find that check box. What am I missing?

    Open the vi and the checkbox is in the file->properties dialog. Once you open the dialog, select "execution" from the drop down and you will find the checkbox there.
    CLA, LabVIEW Versions 2010-2013

  • Intermittent Non-Fatal Lock Ups

    Once every other day or so my Christmas 2008 MBP (10.5.8 / 2.53 GHz Core 2 Duo / 4GB DDR3) with the ~300GB 5,400 rpm HDD locks up.
    When I'm using the computer (not that hard) about 5 open Safari tabs, iTunes, Word08, Stickies and preview open the computer will lock up, I hot key Force Quit and wait for about 30 seconds to 90 seconds for Force Quit to appear and when it does all the applications come back to life.
    Question: Is this an early sign of hardware failure such as the HDD?
    Thanks

    Very likely. Some suggestions to help you rid your mac of unnecessary files/apps and just plain old junk. Download a free app. called Disk Inventory X: http://www.derlien.com/. You can browse your HD with this and identify stuff you don't need.
    Download CleanMYMac. Cost about $25 and worth every penny: http://macpaw.com/cleanmymac. This app. will clean your caches, log files, unnecessary language files and uninstall unwanted apps.
    Let us know how this works out.
    Message was edited by: macbig

  • Get a new non carrier locked iPhone?

    Well I canceled my sprint contract and I'm left with a carrier locked iPhone for sprint, well since I bought apple care + I have insurance on phone. My iPhone 4s has battery issues and if I went to apple and they gave me a new iPhone would that new one be carrier free meaning I could take it to AT&amp;T with me? I think that would be the case right?

    Well all the iPhones are the same when new when you activate it to a carrier, the carrier then locks it to its company, so if it's unactivated and they give me unactivated new phone then it's not locked to anything, this should work because I had learned that all the iPhone 4s have same internals because apple designed to work both ways.?

  • Frozen iPod touch with non-working lock button.

    My daughter's iPod has frozen on a web page. The lock button doesn't work so she uses the assistive touch but even that won't work and can't do a hard reset...help,

    Try:                                               
    - iOS: Not responding or does not turn on
    When it says place the iPod in recovery mode,
    Place the iPod in recovery mode using one of these programs:
    For PC
    RecBoot: Easy Way to Put iPhone into Recovery Mode
    or
    http://joshuabailey1997.wordpress.com/2010/09/02/recboot-v1-3/
    If necessary:
    Download QTMLClient.dll & iTunesMobileDevice.dll for RecBoot
    and                                           
    RecBoot tip
    RecBoot may have problems on 64X windows, then try:       
    Tenorshare ReiBoot – Enter & Exit iPhone, iPad, iPod Recovery Mode with a Single Click
    For MAC or PC       
    The Firmware Umbrella - TinyUmbrella
    Installs blootware on PC too
    - If not successful and you can't fully turn the iOS device fully off, let the battery fully drain. After charging for an least an hour try the above again.
    - Try another cable       
    - Try on another computer                            
    - If still not successful that usually indicates a hardware problem and an appointment at the Genius Bar of an Apple store is in order.
    Apple Retail Store - Genius Bar                                     

  • RT executable causes functional global variable VIs to become non-reentrant

    Hi,
    I am having a small issue with functional global variables (Repositories). The attached VI is a sample functional global variable I created that stores double precision numeric values. The VI properties are set to normal execution. I use this VI to pass data between loops running in real time on a PXI platform. When running my application from the project explorer (not creating executable) the VI functions as it should and passes data between my loops with no issues. But when I create a real time executable of my application and run it on the PXI, it does not share data between instances of the VI. My work around this issue is to change the VI properties execution priority to Subroutine but it forces me to modify my VI slightly for this to work (I have to remove the property node). I am not sure why this is happing. I have seen some applications with this VI that appear to function normally in development and in executable with the VI properties execution priority set to Normal. Any comments or suggestions are welcomed.
    I am running LabVIEW 2009, PXI-8186, and Windows XP
    Thanks
    Attachments:
    RT Repository DBL Numeric Command Ver 2.ctl ‏5 KB
    RT Repository DBL Numeric Element Ver 2.ctl ‏5 KB
    RT Repository DBL Numeric Ver 2.vi ‏25 KB

    Many properties require the front panel to be loaded in memory; the property you're using, NumItems, appears to be one of them (look at the help, you'll see that it says "Loads the front panel into memory.")  However, VIs running in an executable on RT do not have front panels, so those property nodes will not work.  If you were to log the error out terminal from the property node in your executable, you should see that an error occurs.  As a result, you're getting a 0 value out of the property node, causing your VI to output unexpected results.
    My recommendation is that you replace the property node with the function GetNumericInfo found in vi.lib\utility\VariantDataType.  It has an output called EnumNames.  Take the size of the EnumNames array and use that in place of the output from the property node.  This will work on RT.
    Note that this has nothing to do with re-entrancy, and the key hint is that the VI works when you remove the property node.

  • Class VIs for access to private Data: reentrant or not?

    I just created in a class some VIs for access to private data (my German translation). I'm talking about these VIs, which enable you to connect your class object to a property node to read or write private class data. These VIs are by default non-reentrant. My question is: what happens, if I try to access two objects of the same class with these property nodes? Does the second object have to wait for the first one to be read? If yes, can I circumvent this by making these VIs reentrant?
    Regards,
    Marc
    CLD
    Solved!
    Go to Solution.

    In theory yes. In pratice it will depend on what you are doing in the private method and the methods it calls.
    Ben
    Ben Rayner
    I am currently active on.. MainStream Preppers
    Rayner's Ridge is under construction

  • Import string programmatically to reentrant VI

    I am working on a multi-language application that includes a reentrant VI. I have been successful at importing a strings file to non-reentrant VIs but seem to have issues importing strings to a reentrant VI. I basically call the reentrant VI dynamically in a loop (open VI ref, import strings file, run VI). The first iteration is error free, but after that it returns error code 1000.
    I know that the import strings function does not execute when the VI is running and that is why I am receiving this error, but my VI is reentrant and set to preallocate clone for each instance. Is this behavior expected when using the import strings function while calling a reentrant VI multiple times? If so, is there a workaround this issue?
    Thanks,
    Cristian
    (Using LabVIEW 9.0f2)
    Solved!
    Go to Solution.

    Ben wrote:
     "...I believe all re-entrant VI's share the FP...."
    If this is true, then I should be able to just import strings on the first iteration of my loop and the strings should change for all of them.
    I made a simple VI of this for testing and found that on the second iteration, the Run VI method returns error code 1000. The loop runs correctly on the first iteration because the reentrant VI was not in memory, but on the second iteration, it seems like when a new reference is made to the reentrant VI, it sees that it is already running in memory.
    From what I understand about reentrant VIs (set to preallocate clone for each instance), they should act very similar to VIT's. Someone correct me if I am wrong.

  • Functional global set as reentrant vi in CLD sample?

    In the CLD atm sample question attached. It set its functional global as a reentrant vi...
    Now let me get this right , a non reentrant vi, no matter how many times it's called, stores its data into one location. So a functional global should be a nonreentrant vi so the functional global can SET the same data in the same place, and GET the same data in the same place.
    Whereas a nonreentrant vi creates clones everytime it is called, and each clone stores a different set of data in a different place. So a functional global should not be a reentrant vi because it cannot retrieve the same copy of data; there are many different data sets stored in different places, the functional global would not know which data set to retrieve.
    But how come this CLD sample set its functional global as reentrant vi and it works???
    Attachments:
    ATM Simulator LV86.zip ‏116 KB

    richjoh wrote:
    In your VI code "Shared clone is selected"
    Below are past from the LV manual --
    "Memory Usage - Only allocates clone VIs for the maximum number of simultaneous calls to the reentrant VI. Decreases memory usage..."
    "Execution Speed - Creates clone VIs on demand. Slightly decreases execution speed and speed may vary per call.."
    ...and Preallocate is versa of above.
    Yes the only reason to use Reentrant in any LV example is to keep separate copies in memory. This author uses the reentrant VI to track 3 different transaction in his example (looks like an banking ATM, I have not run it as yet). The author reentrant is for "deposit", "withdrawal" and "pin entry". Ctrl+F, the VI is used in 4 instances, one of them is to Get current action, the other 3 are Set.
    IMHO, the example is overblown. Wonder how long it took the author to create it?
    The reason it works is all access is sequential.
    Overblown, yes. Reminds of the kid trying to show-off by climbing over the fence to pose next to the lion's cage. It will bite them eventually.
    Keep It Simple Sir has clearly bee violated.
    I will watch for someone who can explain WHY that was a good decision unless they felt there would 500 of these ATM GUIs running in parallel.
    Ben
    Ben Rayner
    I am currently active on.. MainStream Preppers
    Rayner's Ridge is under construction

  • LOCK 문제 해결을 위한 SCRIPT

    제품 : ORACLE SERVER
    작성날짜 : 2002-04-12
    LOCK 문제 해결을 위한 SCRIPT
    ============================
    Purpose
    Lock이 걸리는 여러가지 현상에 대한 확인과 조치 방법을 알아보자.
    Explanation
    1. LOCK 문제를 일으키는 SQL 명령 찾기
    (1) 다음 Query는 Lock과 관련된 transaction을 출력해준다.
    column username format a10
    column sid format 999
    column lock_type format a15
    column MODE_HELD format a11
    column MODE_REQUESTED format a10
    column LOCK_ID1 format a8
    column LOCK_ID2 format a8
    select a.sid,
    decode(a.type,
    'MR', 'Media Recovery',
    'RT', 'Redo Thread',
    'UN', 'User Name',
    'TX', 'Transaction',
    'TM', 'DML',
    'UL', 'PL/SQL User Lock',
    'DX', 'Distributed Xaction',
    'CF', 'Control File',
    'IS', 'Instance State',
    'FS', 'File Set',
    'IR', 'Instance Recovery',
    'ST', 'Disk Space Transaction',
    'IR', 'Instance Recovery',
    'TS', 'Temp Segment',
    'IV', 'Library Cache Invalidation',
    'LS', 'Log Start or Switch',
    'RW', 'Row Wait',
    'SQ', 'Sequence Number',
    'TE', 'Extend Table',
    'TT', 'Temp Table',
    a.type) lock_type,
    decode(a.lmode,
    0, 'None', /* Non Lock equivalent */
    1, 'Null', /* N */
    2, 'Row-S (SS)', /* L */
    3, 'Row-X (SX)', /* R */
    3, 'Row-X (SX)', /* R */
    4, 'Share', /* S */
    5, 'S/Row-X (SSX)', /* C */
    6, 'Exclusive', /* X */
    to_char(a.lmode)) mode_held,
    decode(a.request,
    0, 'None', /* Mon Lock equivalent */
    1, 'Null', /* N */
    2, 'Row-S (SS)', /* L */
    3, 'Row-X (SX)', /* R */
    4, 'Share', /* S */
    5, 'S/Row-X (SSX)', /* C */
    6, 'Exclusive', /* X */
    to_char(a.request)) mode_requested,
    to_char(a.id1) lock_id1, to_char(a.id2) lock_id2
    from v$lock a
    where (id1,id2) in
    (select b.id1, b.id2 from v$lock b where b.id1=a.id1 and
    b.id2=a.id2 and b.request>0);
    (2) 출력 결과
    SID LOCK_TYPE MODE_HELD MODE_REQUE LOCK_ID1 LOCK_ID2
    5 Transaction Exclusive None 262172 90
    6 Transaction None Exclusive 262172 90
    9 Transaction None Exclusive 262172 90
    SID 6과 9는 SID 5가 걸고 있는 Lock이 풀리기를 기다리고 있음을 알 수 있다.
    2. Lock 관련된 테이블 확인하기
    (1) 다음 Query는 Lock과 관련된 테이블을 출력해 준다.
    column username format a10
    column lockwait format a10
    column sql_text format a80
    column object_owner format a14
    column object format a15
    select b.username username, c.sid sid, c.owner object_owner,
    c.object object, b.lockwait, a.sql_text SQL
    from v$sqltext a, v$session b, v$access c
    where a.address=b.sql_address and
    a.hash_value=b.sql_hash_value and
    b.sid = c.sid and c.owner != 'SYS';
    (2) 출력결과
    USERNAME SID OBJECT_OWNER OBJECT LOCKWAIT
    SQL
    LTO2 6 LTO EMP C3D320F4
    update lto.emp set empno =25 where empno=7788
    LTO3 9 LTO EMP C3D320C8
    delete from lto.emp where empno=7788
    LTO 5 LTO DEPT
    insert into lto.dept values (60,'PROGRAMMER','LOS ANGELOS')
    여기서는 USERNAME에 나와있는 유저가 OBJECT에 나와있는 테이블을 수정하려고
    함을 나타낸다. LT02, LT03는 LT0가 Commit, Rollback 하기를 기다리고 있음을
    알 수 있다. 하지만 여기에는 가장 최근의 DML 명령 하나만 나와있기 때문에
    여기 나온 명령이 반드시 Lock을 걸고 있는 명령이라고 단정지을 수는 없다.
    3. LOCK과 관련된 프로세스 찾기
    (1) 다음 Query를 실행해 보면 프로세스와 관련된 정보를 얻을 수 있다.
    column "ORACLE USER" format a11
    column SERIAL# format 9999999
    column "OS USER" format a8
    select substr(s.username,1,11) "ORACLE USER", p.pid "PROCESS ID",
    s.sid "SESSION ID", s.serial#, osuser "OS USER",
    p.spid "PROC SPID",s.process "SESS SPID", s.lockwait "LOCK WAIT"
    from v$process p, v$session s, v$access a
    where a.sid=s.sid and
    p.addr=s.paddr and
    s.username != 'SYS';
    (2) 위의 Query를 실행하면 다음과 같은 결과가 출력된다.
    ORACLE PROCESS SESSION SERIAL# OS USER PROC SESS LOCKWT
    USER ID ID SPID SPID
    LTO 19 5 31 usupport 17312 17309
    LTO2 25 6 43 usupport 17313 17310 C3D320F4
    LTO3 26 9 1 usupport 17314 17311 C3D320D8
    (3) 조치 방법
    a. LTO에게 Commit, Rollback 할 것을 요구한다.
    b. SQLDBA>ALTER SYSTEM KILL SESSION '5,31';
    c. %kill -9 17309 (유닉스상의 Shadown Process)
    stop/id=<SESS SPID> (PROC SPID=SESS SPID on vms running single task)
    여기서 SYS 유저는 제외시켰는데 필요하다면 Query의 Where 조건에서
    s.username != 'SYS' 부분을 삭제하면 된다.
    4. CATBLOCK.SQL & UTLLOCKT.SQL
    $ORACLE_HOME/rdbms/admin 디렉토리에 있는 스크립트 가운데 catblock.sql과
    utllockt.sql을 사용하여서 Lock 상황을 쉽게 파악할 수 있다.
    (1) 실행 방법
    %cd $ORACLE_HOME/rdbms/admin
    %sqldba lmode=y (svrmgrl
    SVRMGR>connect internal
    SVRMGR>@catblock
    (2) 결과 확인
    column waiting_session format a8
    select lpad(' ',3*(level-1)) || waiting_session,
    lock_type,
    mode_requested,
    mode_held,
    lock_id1,
    lock_id1,
    lock_id2
    from lock_holders
    connect by prior waiting_session = holding_session
    start with holding_session is null;
    WAITING_ LOCK_TYPE MODE_REQUE MODE_HELD LOCK_ID1 LOCK_ID2
    5 None
    6 Transaction Exclusive Exclusive 262172 90
    9 Transaction Exclusive Exclusive 262172 90
    여기서 Session 6, Session 9가 Session 5를 기다리고 있음을 알 수 있다.
    5. Lock & Hanging 문제를 추정하는 방법
    프로그램 상에서 어느 부분이 Lock, Hanging 문제를 일으키는지 알아내기가
    여의치 않을때 다음과 같은 방법을 사용해 보기 바란다.
    (1) init<SID>.ora의 sql_trace=ture로 세팅하면 연관된 SQL 명령이 출력될
    것이다.
    (2) OS 상에서도 Process 상태를 점검하여 본다.
    (3) OS 상의 Debugging 기능을 사용하거나 만약 가능하다면 oradbx를 사용한다.
    Platform 에 따라서 없을 수도 있다.
    (4) 여러가지 Monitoring 방법과 Locking/Blocking 스크립트를 이용한다.
    6. PROCESS STACKS 확인
    때로는 Hanging Process나 리소스를 점유하고 있는 Process의 Process Stack을
    점검해 보는 것이 문제 해결에 도움이 되는 경우가 있다.
    (1) OS Debugging 프로그램을 이용하여 Hangup 되기 전의 마지막 Call을
    확인한다.
    ex)%truss -p <shadow pid>
    (2) oradbx(오라클 debugging 프로그램)은 Support,Development 시에만
    사용된다.
    (3) oradbx 사용예제
    select substr(s.username,1,11) "ORACLE USER" ,
    p.pid "PROCESS ID", s.sid "SESSION ID", s.serial#,
    osuser "OS USER", p.spid "PROC SPID"
    from v$session s, v$access a, v$process p
    where a.sid=s.sid and
    p.addr=s.paddr and
    s.username != 'SYS';
    위의 Query를 실행하면 다음과 같은 결과가 출력된다.
    ORACLE PROCESS SESSION SERIAL# OS USER PROC SESS LOCKWT
    USER ID ID SPID SPID
    LTO 19 5 31 usupport 17312 17309
    LTO2 25 6 43 usupport 17313 17310 C3D320F4
    LTO3 26 9 1 usupport 17314 17311 C3D320D8
    만약 oradbx가 없다면 다음과 같이 해서 만들어 준다.
    %cd $ORACLE_HOME/rdbms/lib
    %make -f oracle.mk oradbx
    LTO Process가 무엇을 하고 있는지 알고 싶으면 Process Stack을 보면 알수
    있다.
    ps -ef | grep 17312
    usupport 17312 17309 0 Sep 15 ? 0:00 oracleV713(DESCRIPTION=(LOCAL=YE
    type <oradbx>
    debug 17312 (이 유저의 oracle shadow process)
    dump stack
    dump procstat
    위에서 생성된 트레이스 화일(user_dump_dest 에 생성됨)을 이용하면
    Hanging 문제를 해결하는데 큰 도움이 된다.
    7. 자주 발생하는 LOCK 문제들
    (1) Parent-Child 관계로 묶인 테이블에서 Child 테이블에 Index가 없는
    상황에서 Child 테이블을 수정하게 되면 Parent테이블에 TABLE LEVEL
    SHARE LOCK이 걸리게 되어서 Parent 테이블에 대한 모든 Update가
    금지된다.
    (2) 블럭의 PCTFREE가 매우 작다면 한 블럭에 여러개의 레코드가 들어 있기
    때문에 한 블럭에 과도한 트랜잭션이 들어와서 블럭의 Transaction
    Layer가 Release 되기를 기다리게 되는 경우도 있다.
    (3) 예제
    create table test (a number) initrans 1 maxtrans 1;
    SYSTEM: insert into test values (5); /* completed */
    SCOTT: insert into SYSTEM.test values (10); /* Scott waits */
    SID OWNER LOCK_TYPE MODE_HELD MODE_REQUE LOCK_ID1 LOCK_ID2
    7 System Transaction Exclusive None 196639 54
    10 Scott Transaction None Share 196639 54

  • Reentrant top level vi

    I have a fairly large top level application vi which contains a number of non-reentrant Functional Globals.  It is a cRIO RT application.  The product which this LV application supports is modular.  That is, the end product is being expanded by integrating a duplicate set of the hardware.  From a software control standpoint, the same LV application could be used to support the expansion.  Thus, on the cRIO a second instance of the top level application vi running from a parallel loop would do the job.  However, because of the non-reentrant Function Globals this will not work because state needs to be maintained.  I see two options for a solution:
    1) Duplicate the top level vi hierarchy with unique file names for all functional global vi's.  This would be very inefficient.
    2) Change the functional global vi's to re-entrant, pre-allocated.  This may be the best, but has it's issues because the application calls these vi's in different places.
    Any other suggestions to manage a modular architecture like this?

    Here, I got it to work.
    You make your functional global a non-reentrant template and you make your top level vit a reentrant vi template. Then when you launch the top level vit dynamically you will get two independent instances of the functional global. I used VI server methods but you could most likely use start async call if you are using LabVIEW 2012.
    Run the Main.vi and you will see that each launched template VI increments its counter independent of the counter in the other vit.
    CLA, LabVIEW Versions 2010-2013
    Attachments:
    vitemplates.zip ‏25 KB

Maybe you are looking for