<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.foxite.com/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>vivekdeodhar</title><link>http://weblogs.foxite.com/vivekdeodhar/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>How to use record locking (rlock()) with MySQL tables </title><link>http://weblogs.foxite.com/vivekdeodhar/archive/2009/12/02/REcord_Locking_in_Mysql.aspx</link><pubDate>Wed, 02 Dec 2009 15:25:00 GMT</pubDate><guid isPermaLink="false">8827bd1c-7596-4a8f-b0de-f59ce9ede522:9544</guid><dc:creator>vivekdeodhar</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.foxite.com/vivekdeodhar/comments/9544.aspx</comments><wfw:commentRss>http://weblogs.foxite.com/vivekdeodhar/commentrss.aspx?PostID=9544</wfw:commentRss><description>&lt;br&gt;&lt;font size="2"&gt;&lt;span&gt;When I started thinking of shifting my back-end from VFP tables to Mysql, I was&lt;/span&gt;&lt;br&gt;&lt;span&gt;confronted with the problem of non-availability of "rlock()" with mysql tables.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;In all cases, I wanted to use "rlock", because I did not want two users to start&lt;/span&gt;&lt;br&gt;&lt;span&gt;working on same record in a table at the same time. Why?&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Take an example of Sale invoice entry. I have two tables, one "sale" and another "saleitems".&lt;/span&gt;&lt;br&gt;&lt;span&gt;First one holds common data like date, customer name etc and the other one holds &lt;/span&gt;&lt;br&gt;&lt;span&gt;item codes,qty,rate etc. for each item in that sales invoice.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;If two users edit same invoice at the same time, since there is no lock, both will be allowed&lt;/span&gt;&lt;br&gt;&lt;span&gt;to get their own cursors and can make changes. Only at the time of saving, one of them will be&lt;/span&gt;&lt;br&gt;&lt;span&gt;told that "underlying data has changed. What do you want to do?"&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Some invoices of my customers are really big and complex, and naturally, they would want to know&lt;/span&gt;&lt;span&gt; if someone is working on it, BEFORE another one starts editing, and NOT at the time of saving.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Actually, there are functions called "get_lock()", "release_lock" and "is_used_lock()" in mysql.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;get_lock('anything',timeout) creates a lock by name of 'anything' and no other user/session can use&lt;/span&gt;&lt;span&gt; lock name 'anything'. However the problem is that when you use release_lock(), ALL locks created by&lt;/span&gt;&lt;span&gt; session calling release_lock() are released!&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;The workaround is to create a unique user ID for each thread at application startup and place a lock by &lt;/span&gt;&lt;span&gt;using get_lock() on it.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Create a mysql table which holds locking reference (table name+ID of the row to lock) and the user's unique ID.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Whenever you want to use "rlock()" functionality, insert the locking reference and user ID into this table.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;For example, if your unique ID is "2T30W763R" and you want to lock row having ID 345765 in table "invoice",&lt;/span&gt;&lt;span&gt; you insert ("invoice345765","2T30W763R") into this table.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;If some other user wants to edit this record, the code first looks up whether this "invoice345765" exists in the&lt;/span&gt;&lt;span&gt; table. If yes, check whether the first users still holds the lock. This is necessary because, after starting&lt;/span&gt;&lt;span&gt; work and placing a lock, first user's application might have crashed, powered out etc. If this happens, mysql&lt;/span&gt;&lt;span&gt; table would still hold the lock row information, but actual mysql lock placed by that user at application startup terminates automatically if first user's connection handle goes out of scope.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;This can be verified by checking is_used_lock(first user's unique ID). This ID is available from lock table's row.&lt;/span&gt;&lt;span&gt; If the lock is valid, then this record is actually locked, otherwise the second user deletes this row and inserts another&lt;/span&gt;&lt;span&gt; row by his/her unique ID.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;User removes inserted row when the lock is no longer required, so that other users wishing to work on that record can&lt;/span&gt;&lt;span&gt; acquire lock &lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span&gt; on it &lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span&gt;(by inserting a row) and start working.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;The entire code is given below. Comments are placed wherever I felt necessary. You should change the "&lt;/span&gt;&lt;span&gt;yourschemaname&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;span&gt;,"&lt;/span&gt;&lt;span&gt;oConn&lt;/span&gt;&lt;span&gt;" and &lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span&gt;"&lt;/span&gt;&lt;span&gt;autoincID&lt;/span&gt;&lt;span&gt;" &lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span&gt;to whatever is your actual value.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="2"&gt;&lt;span&gt;*********MYSQL DATABASE PART ***************&lt;/span&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;A. Create a table in your schema to hold lock information.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Note: First column holds table name+rowID to lock &lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Second column holds user's unique ID (see below for details about this user ID)&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;DROP TABLE IF EXISTS `&lt;/span&gt;&lt;span&gt;yourschemaname&lt;/span&gt;&lt;span&gt;`.`locklist`;&lt;/span&gt;&lt;br&gt;&lt;span&gt;CREATE TABLE&amp;nbsp; `&lt;/span&gt;&lt;span&gt;yourschemaname&lt;/span&gt;&lt;span&gt;`.`locklist` (&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp; `lcknm` char(40) NOT NULL,&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp; `unqid` char(10) NOT NULL,&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp; PRIMARY KEY (`lcknm`),&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp; KEY `locklist_unqid` (`unqid`) USING BTREE&lt;/span&gt;&lt;br&gt;&lt;span&gt;) ENGINE=InnoDB DEFAULT CHARSET=latin1;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;span&gt;B. Create a stored Procedure named "testlock".&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;DELIMITER $$&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;DROP PROCEDURE IF EXISTS `&lt;/span&gt;&lt;span&gt;yourschemaname&lt;/span&gt;&lt;span&gt;`.`testlock` $$&lt;/span&gt;&lt;br&gt;&lt;span&gt;CREATE DEFINER=`root`@`%` PROCEDURE `testlock`(mylcknm varchar(40))&lt;/span&gt;&lt;br&gt;&lt;span&gt;BEGIN&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;set @lockres=null,@otherunqid=null,@otherconn=null,@rowsinres=null;&lt;/span&gt;&lt;br&gt;&lt;span&gt;select unqid into @otherunqid from locklist where lcknm=mylcknm;&lt;/span&gt;&lt;br&gt;&lt;span&gt;if not @otherunqid IS NULL then&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; select is_used_lock(@otherunqid) into @otherconn;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; if @otherconn IS NULL then&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update locklist set unqid=@myunqid where lcknm=mylcknm;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select row_count() into @rowsinres;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not @rowsinres&amp;gt;0 then&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @lockres=2;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @lockres=1;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end if;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delete from locklist where unqid=@otherunqid;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @lockres=3;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; end if;&lt;/span&gt;&lt;br&gt;&lt;span&gt;else&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; insert into locklist (lcknm,unqid) values (mylcknm,@myunqid);&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; select row_count() into @rowsinres;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not @rowsinres&amp;gt;0 then&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @lockres=4;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @lockres=1;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end if;&lt;/span&gt;&lt;br&gt;&lt;span&gt;end if;&lt;/span&gt;&lt;br&gt;&lt;span&gt;select @lockres lockresult,@otherconn othcon;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;END $$&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;DELIMITER ;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;font size="2"&gt;&lt;span&gt;*********MYSQL DATABASE PART COMPLETE***********&lt;/span&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;************VFP PART ******************&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;&lt;span&gt;C. Create unique ID for your mysql session.&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;Insert this code after you get mysql connection handle&lt;/span&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;&lt;span&gt;oConn in my case&lt;/span&gt;)&lt;br&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; Note:&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; This Code creates a unique(well, for my purpose, it is sufficiently unique) ID. It is stored &lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; as _screen.unqid and a mysql lock is placed against this name.&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; addproperty(_screen,'unqid',sys(2015,10))&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; if not sqlexec(&lt;/span&gt;&lt;span&gt;oconn&lt;/span&gt;&lt;span&gt;,"select get_lock(?_screen.unqid,10)","lockres")=1&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqldisconnect(&lt;/span&gt;&lt;span&gt;oconn&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; messagebox('Connected but could not get global lock handle.'+chr(13)+'Please log in again',16,'')&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; endif&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; if used('lockres')&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; use in lockres&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; endif&lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlexec(oconn,"set @myunqid=?_screen.unqid")&amp;nbsp; &amp;amp;&amp;amp; create mysql unique ID variable so we can use it throughout in SP&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; (REMEMBER that you should not use release_lock() anywhere in your application or&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this lock will also be released!)&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;D. Create following property in your form&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; Property Name : idlocked , Value : None&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;E. Create a method in your form named "islocked" and paste following into it.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;**tests if current record can be locked in mysql. called from forms' edtbtn&lt;/span&gt;&lt;br&gt;&lt;span&gt;lparameter lcidlocked&lt;/span&gt;&lt;br&gt;&lt;span&gt;local lcalias,lclockyn,lnlockresult&lt;/span&gt;&lt;br&gt;&lt;span&gt;store alias() to lcalias&lt;/span&gt;&lt;br&gt;&lt;span&gt;sele 0&lt;/span&gt;&lt;br&gt;&lt;span&gt;if not sqlexec(&lt;/span&gt;&lt;span&gt;oconn&lt;/span&gt;&lt;span&gt;,"CALL testlock('"+lcidlocked+"')")&amp;gt;0 &amp;amp;&amp;amp;calls the stored procedure&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;retu .f.&lt;/span&gt;&lt;br&gt;&lt;span&gt;endif&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;*SP will return a cursor holdng the result integer.&lt;/span&gt;&lt;br&gt;&lt;span&gt;*get return value from cursor returned by SP and close it.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;lnlockresult=val(lockresult) &amp;amp;&amp;amp;lockresult is field in returned cursor&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;do case&lt;/span&gt;&lt;br&gt;&lt;span&gt;case lnlockresult=1&amp;nbsp; &amp;amp;&amp;amp; success&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; lclockyn=''&lt;/span&gt;&lt;br&gt;&lt;span&gt;case lnlockresult=2&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; lclockyn='Previous lock expired but could not set new Lock to this Record.'&lt;/span&gt;&lt;br&gt;&lt;span&gt;case lnlockresult=3&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; lclockyn='Record is Locked by other user under Connection ID : '+trans(othcon) &amp;amp;&amp;amp;othcon is field in returned cursor&lt;/span&gt;&lt;br&gt;&lt;span&gt;case lnlockresult=4&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; lclockyn='No other lock but could not set new Lock to this Record.'&lt;/span&gt;&lt;br&gt;&lt;span&gt;otherwise &amp;amp;&amp;amp;null or error&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; lclockyn='Undefined error returned by database.'&lt;/span&gt;&lt;br&gt;&lt;span&gt;endcase&lt;/span&gt;&lt;br&gt;&lt;span&gt;use&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;if used(lcalias)&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; sele (lcalias)&lt;/span&gt;&lt;br&gt;&lt;span&gt;endif&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;if empty(lclockyn)&amp;nbsp; &amp;amp;&amp;amp;lock ok&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; thisform.idlocked=lcidlocked&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; retu .t.&lt;/span&gt;&lt;br&gt;&lt;span&gt;else &amp;amp;&amp;amp;lock failed&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; thisform.idlocked=''&amp;nbsp; &amp;amp;&amp;amp;for safety&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; messagebox(lclockyn,16,'Message')&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; retu .f.&lt;/span&gt;&lt;br&gt;&lt;span&gt;endif&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;F. Insert the following code into your edit button "click" (insert this at the beginning).&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Note:&lt;/span&gt;&lt;br&gt;&lt;span&gt;for example, if you want to lock record in mysql table "invoice" which has autoinc id 345765,&lt;/span&gt;&lt;br&gt;&lt;span&gt;then your code will be &lt;/span&gt;&lt;br&gt;&lt;span&gt;lclockname="invoice"+trans(345765)&lt;/span&gt;&lt;br&gt;&lt;span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;local lclockname&lt;/span&gt;&lt;br&gt;&lt;span&gt;lclockname=yourfilename+trans(your actual autoincID of row to lock)&lt;/span&gt;&lt;br&gt;&lt;span&gt;if not thisform.islocked(lclockname)&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; retu .f.&lt;/span&gt;&lt;br&gt;&lt;span&gt;endif&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;G. Use the following code for removing locked row name from table "locklist" when your editing is complete.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Note:&lt;/span&gt;&lt;br&gt;&lt;span&gt;Your lock's name is already stored into form property "idlocked" at the time of placing the lock.&lt;/span&gt;&lt;br&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span&gt;You can create another method named "removelock" in your form class and place this code into it.&lt;/span&gt;&lt;/font&gt;&lt;br&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;span&gt;sqlexec(&lt;/span&gt;&lt;span&gt;oconn&lt;/span&gt;&lt;span&gt;,"delete ignore from locklist where lcknm=?thisform.idlocked")&lt;/span&gt;&lt;br&gt;&lt;span&gt;thisform.idlocked=''&lt;/span&gt;&lt;br&gt;&lt;span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;H. Remove mysql lock on userid when closing application&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; sqlexec(&lt;/span&gt;&lt;span&gt;oconn&lt;/span&gt;&lt;span&gt;,"do release_lock(?_screen.unqid)")&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;&lt;br&gt;************VFP PART COMPLETE******************&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;In essence, when your framework is complete, you can place locks on mysql table rows just by single command&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;thisform.islocked(lclockname)&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;End.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Vivek Deodhar&lt;/span&gt;&lt;br&gt;&lt;span&gt;02-12-2009&lt;/span&gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;&lt;img src="http://weblogs.foxite.com/aggbug.aspx?PostID=9544" width="1" height="1"&gt;</description></item></channel></rss>