Welcome to the SRP Forum! Please refer to the SRP Forum FAQ post if you have any questions regarding how the forum works.

How can I check if I have a lock without locking or unlocking

edited March 2019 in OpenInsight
Hi,

Do you know if it's possible to check in code if I have the lock on a particular record without actually locking or unlocking said record?

I know that I could check this by running the lock or unlock statement, but i'd rather not, as I want to only check. Running either of the above statements will have the side effect that I lock and unlock the record.

To give you some background:

as you know, the internal tool that Revelation provides to check locks doesn't work (It causes our entire system to crash. We had a person from Revelation come to our office to fix it, but he couldn't fix it...)

So the idea is to have each workstation (inside of the TIMER EVENT) check if it has the lock.

Also, RTI_Lock_Owner doesn't work. We have tested it, and it just doesn't work.

Comments

  • This question was asked recently on the Revelation forum by our friend M@. He didn't get a response from Revelation but our other friend Barry Stevens suggestion RTI_Lock_Owner. I'm not sure if this gave M@ what he needed.

    We are aware that RTI_Lock_Owner is unreliable, especially with older versions of the UD (v4 and earlier). There is a lower level routine called RTI_LH_INFO that is supposed to be more reliable, but we have still found some issues with it.
  • ok thanks. We will just use the unlock statement. It's not ideal, but it will do.

    Thanks
  • What I did was first check if there is an active connection to the Linear Hash service (v4.7.2). If so then I'll use RTI_Lock_Owner() to determine the lock status; otherwise I'll test the lock manually.
    isLocked = false$ lockStatus = '' If SRP_Array( 'Join', NTSserial()< 2>, 'N/A', 'NOT', @vm) != '' then // Get lock info directly from the active LH service lockOwner = RTI_Lock_Owner( dataFile, dataId) If lockOwner != '' then isLocked = true$ lockStation = field( lockOwner, '*', 3) ;// assuming LH v4.7.2 lockStatus = (lockStation == @station) End end else // Test the lock manually Open dataFile to lockFv then Lock lockFv, dataId then lockStatus = status() Unlock lockFv, dataId else null isLocked = true$ End End End
    The NTSserial() function will return the server names and LH service serial number for the attached files. I found that calling RTI_Lock_Owner (or List_User_Locks)) can add any servers it finds to this list, even for files not attached! That's why in the code above, RTI_Lock_Owner() is only used if there are no instances of a server without a service.

    Also, while RTI_Lock_Owner() can tell you the lock status without producing a temporary physical lock, it is veeery sloow compared to just a Lock statement (probably because of the network interrogation it does). Its use seems to degrade performance of the LH service, affecting all sessions (at least for locking).

    HTH, M@
  • @MattCrozier

    i dont' really get this
  • As far as I know, using RTI_Lock_Owner() with a Linear Hash service is the only way you can test a lock without physically placing a lock. So this method depends on it being reliable, of course. I found that it did what it was supposed to do in my situation (using UD v4.7.2) - just with some weird side effects on the NTSserial() function. I was only using it for diagnostic 'spying' though - not in production code.
  • found I use this code

    function bsbs_get_lock_owner(Filename, Key) Declare Function rti_lock_owner owner = RTI_Lock_Owner( Filename ,Key ) if index(owner,'*',1) then PcId=field(Owner,'*',2,2)[1,'_'] end else PcId=owner end SysloginsRec=xlate("SYSLOGINS",owner,'','X') if SysloginsRec then UserId=SysloginsRec<10> if UserId then PCId:=" [":UserId:"]" end end return PCId
  • hi,

    rti lock owner doesn't work for us.

    Anyway, we now have a solution that is 100% correct.
  • >>Anyway, we now have a solution that is 100% correct.

    Which is?
  • edited September 2019
    We do 2 things:

    1. We have an MFS on some (but not all) tables that tracks locks and unlocks. This is 100% correct for the tables that it tracks. Note that if a workstation with locks crashes, then the workstation's locks will not be cleared. But this problem can be fixed very easily: the program that reports the locks checks if the lock it is supposed to report is a valid lock, which it does by running the lock statement. If the lock statement returns true, then that means the person who is reported to have the lock doesn't actually have it.

    2. We have code that runs every minute on every workstation that checks if it has the lock. If the workstation is not idle and never goes idle, this won't work. But if a workstation doesn't respond within a certain time, we can check it manually.

  • Note that if a workstation with locks crashes, then the workstation's locks will not be cleared.

    Eventually the UD will clear the lock. I think the default timeout is 30 minutes but I believe this can be changed.
    We have code that runs every minute on every workstation that checks if it has the lock.

    I assume this means you are using a TIMER event (or perhaps the IDLEPROC property).
  • edited September 2019
    @donbakke
    "Eventually the UD will clear the lock. I think the default timeout is 30 minutes but I believe this can be changed."

    Oh no, you have misunderstood me. I am not talking about OI's tracking of the locks. I'm talking about our custom built system for tracking locks, which consists of a table that stores who currently has the lock. We update this table in an MFS which is triggered whenever a LOCK or UNLOCK statement is run. Unfortunately, the UNLOCK ALL statement doesn't trigger the MFS, but we don't use this statement very much in our code base, so it's not an issue.


    "I assume this means you are using a TIMER event (or perhaps the IDLEPROC property)."
    Yeah, the TIMER event, which runs every minute.
  • But you are still relying upon the UD for lock management, correct? That is, you are using the LOCK and UNLOCK statements which means you are asking OI (and ultimately the UD) to enforce and release the locks.

    Consider using the IDLEPROC property instead. It will be less intrusive than the TIMER event.
  • "But you are still relying upon the UD for lock management, correct? That is, you are using the LOCK and UNLOCK statements which means you are asking OI (and ultimately the UD) to enforce and release the locks."
    Yes, true.

    "Consider using the IDLEPROC property instead. It will be less intrusive than the TIMER event."
    Ok sure, wasn't aware of that.
  • I assumed, then, that when you commented that "if a workstation with locks crashes, then the workstation's locks will not be cleared" this was a reference to the true lock not be clearing. If that is the case, then my previous comment is applicable. The UD (not the UD Manager, but the actual Universal Driver) will eventually release stale locks.
  • edited September 2019
    Yeah it will release the lock, but our own table that stores lock info will not have been updated. That's what I was referring to. Also, i didn't know that you could set a property that controls the time after which a user has been logged off that OI release his locks. Ours must be set to instant, because i have tested this, and it happens instantly.
  • "Eventually the UD will clear the lock. I think the default timeout is 30 minutes but I believe this can be changed."

    Resurrecting the thread.. How can this default timeout be changed?

    Thanks!
Sign In or Register to comment.