aquireLock madness

Hi! For some time (over 3 years), we’ve been using a bit of code which helps us number our clients’ Invoice ID’s, Inventory ID’s etc.

We’ve been moving our code to Servoy 6.

In the development environment we have, this code works nicely.

In the production environment, we cannot acquire the lock, and there for, the method hangs.

Both environments are using MySQL
The production environment on Servoy 4 uses the same code on the same MySQL db, and it works.

Any ideas why after changing to Servoy 6, it hangs?

function getInvoiceID(event, arg0, arg1)
{
//search on the form (lets call it Customers) and find that customer

var customerID = arg0 //arguments[0]
var transtype = arg1 //arguments[1]
var frm = 'cji_frm_customer_accounts'

var fld;

if (transtype == 'S')
{
	fld = 'last_invoice_id'
}
else if (transtype == 'P')
{
	fld = 'last_po_id'
}
else if (transtype == 'A')
{
	fld = 'last_adj_id'
}
else if (transtype == 'T')
{
	fld = 'last_trans_id'
}
else if (transtype == 'C')
{
	fld = 'last_credit_id'
}


if (forms[frm].controller.find())
{

	forms[frm].cji_customer_id = customerID
	var count = forms[frm].controller.search()

	var fs = forms[frm].foundset
	var lockCount = 0
	
	if(count == 1) //customer record was found
	{
		var success = false
	
		while(!success)	//loop until we can get the record
		{
			success = databaseManager.acquireLock(fs,0,fld)  <--- fails right here... success comes back as a false
			
			if(success)
			{
				databaseManager.refreshRecordFromDatabase(forms[frm].foundset, 1)
				forms[frm].last_invoice_id = forms[frm].last_invoice_id + 1 //assuming lastInvoiceID is your column name			
				if (!forms[frm][fld]) {forms[frm][fld] = '1000'} // if there is no number, we start with a default
				var setFrm = forms[frm][fld] = forms[frm][fld] + 1 //assuming lastInvoiceID is your column name
							
				var thySave = databaseManager.saveData()	
				if (!thySave)
				{
					//var errSave = databaseManager.getLastDatabaseMessage()
					var errRecs = databaseManager.getFailedRecords()
					databaseManager.rollbackEditedRecords()
					//application.setStatusText(errSave);							
					return false;
				}

				databaseManager.releaseAllLocks(fld)
				return forms[frm][fld] //return the value back
			}
			else
			{
				application.sleep(1000) //1000 miliseconds = 1 second
				lockCount = lockCount + 1
				if (lockCount > 10)
				{
					globals.setMessagePrompt(event,'Error: There was a problem obtaining the ID from the database. [getInvcoiceID]',4,3)
					return false;
				}
				
			}
		}
	}
}
else
	return null;
	
	return null;
}

Hi.

So I see you are acquiring a lock on the currently selected record of that foundset.
As long as you have 1 record which seems to be true, selected record should be ok (if there would be no selected record it would return false).

It is possible that you lock that record, then your code fails with some exception and the lock is never released. Then no other client can acquire it.
Try doing something like:

success = databaseManager.acquireLock(fs,0,fld);         
if (success) {
    try {
        (...)
    } finally {
        databaseManager.releaseAllLocks(fld);
    }
}

Do you see any errors in the log in the (…) part of code before you can no longer acquire locks?

I also see now that you actually have a return that may happen before the lock release.
That is a very very bad idea. So it’s possible that you do not release the lock because a save fails.

Thanks for the responses.

The error fires when I try to acquire the lock. So, yes, I need to add a releaseAllLocks in the area where I’m doing some error checking, but the lock doesn’t happen and it’s the oddest thing.

This code is exactly the same as when we used 4.1.x

I’m stumped.

Add the try-finally to make sure you release locks in any case (even if you have return or an exception is thrown, finally will still execute), maybe add some more debug info for the error checking situation where you would just return without releasing before and see what happens. If the lock is acquired but not released, subsequent attempts to acquire it by other clients will fail…

If this happens again go to admin page → locks where you can see if someone has that lock and will not release it (you can manually release it from there if you are sure it’s not supposed to be acquired). That should help you debug the problem.

I will take those steps. Thanks for the suggestions.

I did a quick work around by not trying the lock and haven’t looked at the problem for awhile. But I’m pretty sure I was getting it in developer.

It was odd because it was code we’ve been using for 3 years and hadn’t adjusted it. But perhaps a new and fresh look will uncover something.