<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Question Re: Need help designing a locking strategy in Technology Q&amp;A</title>
    <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842642#M4873485</link>
    <description>&lt;P&gt;Thank you to everyone who has contributed to this very long thread.  A lot of very useful information has been contributed and I've learned quite a bit from your various contributions.&lt;/P&gt;
&lt;P&gt;First, let me respond to Vlad's suggestion.  Unfortunate, this is not a good fit for our use case.  If we allowed multiple users to all be making long running changes to the row working off of a in a "working" table we would not be able to merge the changes into a new row.  Further, telling all but one of the users that they need to refresh their view and redo all their work would not be acceptable to the users since it would represent the loss of perhaps hours of work.  So unfortunately we aren't able to go with that suggestion.&lt;/P&gt;
&lt;P&gt;I will take Volker's advice and start a new thread that is a follow-on from our discussions here because this has gotten very long and a bit convoluted.  For those who are interested, here is what I have concluded and decided.  As I described earlier, a user who first gets the row lock can interact with the row over perhaps several hours.  It was asked how intermittent saves would be handled in such a scenario.  What I have designed is for the intermittent saves to of, course, do a COMMIT which, of course, causes the lock to be lost.  The user that had the lock immediately tries to reacquire the lock but there's no guarantee the lock will be acquired.  To deal with this I have code so that when anyone tries to obtain a lock and they get they take extra steps to look at certain items in the row to determine if that lock was being held by somebody else and they have "slipped in" between that other user's COMMIT and their attempt to reacquire the lock.  In that case the user "backs off" for a small amount of time and tries again.  With very high probability the original user will be able to quickly reacquire the lock.  I had also mentioned that, at least in its first phase, I wasn't going to worry about notifying other users that the row has become "un-lockable".  So other users are notified that they cannot obtain a lock and they simply have to try again at later date to see if they can then acquire the lock.  However, even in this scenario (if I understand everything that's been discussed in this thread) I still have a long running (single) transaction/worker that has to maintain this very long lock on the row.  Since it is possible for a single user to have multiple rows locked and since we could have running on the server perhaps 100 users it appears that a worst-case scenario would require that several hundred transactions/workers be tied up. Volker suggested using a mutex and I have finally been able to make the time to research this and it appears that that is a simple and clean way to accomplish what I need without tying up any of these transactions/workers.  So, assuming I don't discover something very bad, I'm going to take that route and if anyone is interested in how that develops I have started a new thread labeled "Need help with MUTEXes".  Again thanks to everyone for your contributions and help; this has been very useful.&lt;/P&gt;</description>
    <pubDate>Wed, 23 Aug 2017 19:50:32 GMT</pubDate>
    <dc:creator>Former Member</dc:creator>
    <dc:date>2017-08-23T19:50:32Z</dc:date>
    <item>
      <title>Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaq-p/13842609</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;
&lt;P&gt;I need to lock a table row for a "long" period of time.  I have a row containing a BLOB from which a user is presented with a screen of information that they can interact with for a long (perhaps hours) period of time.  I want the first user that accesses this row to have update ability and all others that access the row to be prevented from altering any row information.  Once that first user is done then another user can obtain "write" permissions.&lt;/P&gt;
&lt;P&gt;The way this could be done is to "set a flag" in the row (or elsewhere) when the row is first accessed and in code test to see if the flag is set and if so block attempts to alter the row data.  However, this has the vulnerability that if that first user crashes or is disconnected in some other way we are left with a permanently locked row (requiring an Admin to detect the problem and then take action to reset the row).  What I have implemented instead uses Level 0 Isolation along with:&lt;/P&gt;
&lt;P&gt;SET TEMPORARY OPTION "blocking" = 'ON';
SET TEMPORARY OPTION "blocking_timeout" = '10000';&lt;/P&gt;
&lt;P&gt;This allows the first user to get a Write lock and other users will get an error so the client code can act as needed.  It takes advantage of the fact that the server (as I understand it) constantly monitors connections and if it detects that a connection has died it frees all associated locks.  That takes care of the connection dying problem and works well except that we are leaving the lock in place for perhaps several hours.  As I understand it that ties up a db connection for all of that time and, at a minimum, makes db connection pooling ineffective, not to mention we are probably going to hit some server limit on connections.  This is for a SQLAnywhere 17 High Availability system.&lt;/P&gt;
&lt;P&gt;What can you comment on/recommend for a better way to accomplish this:&lt;/P&gt;
&lt;P&gt;1) Am i correct in my understanding that the server will free the lock if the connection dies?&lt;/P&gt;
&lt;P&gt;2) Are my fears about exhausting the available connections correct?&lt;/P&gt;
&lt;P&gt;3) Can you recommend a better way to keep a "lock" of some time on a row in place?&lt;/P&gt;
&lt;P&gt;Thank you.&lt;/P&gt;</description>
      <pubDate>Sun, 06 Aug 2017 15:21:56 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaq-p/13842609</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-08-06T15:21:56Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842611#M4873454</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;As I understand it that ties up a db connection for all of that time&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;AFAIK, a blocked transaction also ties up a &lt;STRONG&gt;worker&lt;/STRONG&gt;, which is a more important resource than a connection (although with v12 and above, the number of workers (aka "multiprogramming level") will be increased automatically by default), so that might be a problem or not.&lt;/P&gt;
&lt;P&gt;How exactly does the first transaction get its write lock? By really doing an UPDATE on the row and leaving that transaction open until the user finishes work, or do you issue a blocking SELECT, say via a cursor?&lt;/P&gt;
&lt;HR /&gt;
&lt;P&gt;FWIW, &lt;A href="http://sqlanywhere-forum.sap.com/questions/11267/what-are-best-practices-for-unit-of-work-lock-management"&gt;here's a thread&lt;/A&gt; dealing with a different situation ("unit of work") but also with "long transactions" and with several solutions discussed. With just a few superficial thoughts, I'd think a "non-blocking" solution might be to modify a flag in the table that a user is starting to "do work" (say, by storing his connection number within the row and then committing) and to disallow other users to modify the row when that flag is set. A disconnect event could make sure that the row is "unlocked" when the connection unexceptedly dies. That would not block other users.&lt;/P&gt;
&lt;P&gt;However, you would have to implement your own "notification system" to tell those that the other user's work is done, if that is a requirement, too. On a database level, you could both use "MESSAGE TO CLIENT FOR CONNECTION" / "WAITFOR ... AFTER MESSASE BREAK" or v17's new mutex objects, however, those "waits" would again block the workers servicing the according connections.&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 04:12:56 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842611#M4873454</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-07T04:12:56Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842610#M4873453</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;I need to lock a table row for a
"long" period of time.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Since you are dealing with a single row, and seem to be looking for a simple solution, you may &lt;B&gt;not need&lt;/B&gt; the techniques discussed in &lt;A href="http://sqlanywhere-forum.sap.com/questions/11267/what-are-best-practices-for-unit-of-work-lock-management"&gt;&lt;B&gt;What are best Practices for Unit-of-Work Lock Management?&lt;/B&gt;&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;One way to lock a row against updates is to update the row yourself, right away, before the "long period of time" begins... and let SQL Anywhere's default locking and blocking mechanisms do all the work for you.&lt;/P&gt;
&lt;P&gt;Volker mentioned this technique: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;By really doing an UPDATE on the row and
leaving that transaction open until
the user finishes work.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;One way to do that is to (a) add "update count" or similar small column to the row, and (b) have all connections "signal intent" to update the row by immediately updating the small column without comitting.&lt;/P&gt;
&lt;P&gt;This technique does NOT require any of the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;changes to isolation level &lt;/LI&gt;
&lt;LI&gt;fiddling with database options &lt;/LI&gt;
&lt;LI&gt;special code to release locks when Bad Things Happen&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This technique &lt;B&gt;also does not&lt;/B&gt; fill up the rollback log with blob data for a long period of time because although the whole row is locked, the whole row is not necessarily written to the rollback lock (e.g., when only a small column is actually updated).&lt;/P&gt;
&lt;P&gt;As Volker noted, for each connection that is blocked and waiting, you will be using up one extra server-level ActiveReq (the number of server workers handling client-side requests) out of the MultiProgrammingLevel pool (the maximum number of requests that can be processed at one time)...&lt;/P&gt;
&lt;P&gt;...so the question is, how many users are you expecting to update the same blob at the same time? ( on average, one, right? )&lt;/P&gt;
&lt;P&gt;The following demo assumes you have control over the application architecture, and you can force every connection to attempt the intent-signalling UPDATE before proceeding with their work on the blob.&lt;/P&gt;
&lt;H3&gt;Set up for testing&lt;/H3&gt;

&lt;PRE&gt;CREATE TABLE t ( 
   pkey         INTEGER NOT NULL DEFAULT AUTOINCREMENT PRIMARY KEY,
   update_count INTEGER NOT NULL DEFAULT 1,
   blob         LONG BINARY NOT NULL );

INSERT t ( blob ) 
VALUES ( xp_read_file ( 'C:\\\\projects\\\\foxhound_benchmark_inventory_db\\\\inventory17.db' ) );

-- Show that an INSERT doesn't have to put anything in the rollback log.

SELECT DB_PROPERTY ( 'RollbackLogPages' );

DB_PROPERTY('RollbackLogPages')
'0'

-- Show that an UPDATE of the blob DOES put a lot of data in the rollback log.

UPDATE t
   SET blob = xp_read_file ( 'C:\\\\projects\\\\foxhound_benchmark_inventory_db\\\\inventory16.db' )
 WHERE pkey = 1;

SELECT DB_PROPERTY ( 'RollbackLogPages' );

DB_PROPERTY('RollbackLogPages')
'11423'

-- Show what's in the table, ready for concurrency testing.

COMMIT;

SELECT @@SPID, pkey, update_count, LENGTH ( blob ), @@VERSION FROM t ORDER BY pkey;

@@SPID,pkey,update_count,LENGTH(t.blob),@@VERSION
1,1,1,72130560,'17.0.7.3399'
&lt;/PRE&gt;

&lt;H3&gt;Connection 1 signals intent to update the blob&lt;/H3&gt;

&lt;PRE&gt;UPDATE t
   SET update_count = update_count + 1
 WHERE pkey = 1;

SELECT @@SPID, pkey, update_count, LENGTH ( blob ), @@VERSION FROM t ORDER BY pkey;

@@SPID,pkey,update_count,LENGTH(t.blob),@@VERSION
1,1,2,72130560,'17.0.7.3399'

-- Show that this UPDATE didn't put anything in the rollback log.

SELECT DB_PROPERTY ( 'RollbackLogPages' );

DB_PROPERTY('RollbackLogPages')
'0'
&lt;/PRE&gt;

&lt;H3&gt;Connection 2 blocked from signalling intent&lt;/H3&gt;

&lt;PRE&gt;UPDATE t
   SET update_count = update_count + 1
 WHERE pkey = 1;

-- The block details as shown by Foxhound...

       Blocked By:  1 / dba / Breck / - / ddd17-1 
     Block Reason:  Row Transaction Intent, Row Transaction WriteNoPK lock on dba.t 
 Locked Row Query:  SELECT * FROM dba.t WHERE ROWID ( t ) = 40370176;
   Last Statement:  update  
                      "t"
                      set "update_count" = "update_count"+1
                      where "pkey" = 1
   Last Plan Text:  ( Update [B]
                    ( IndexScan t t )
                    )
&lt;/PRE&gt;</description>
      <pubDate>Mon, 07 Aug 2017 06:57:39 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842610#M4873453</guid>
      <dc:creator>Breck_Carter</dc:creator>
      <dc:date>2017-08-07T06:57:39Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842612#M4873455</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;However, this has the vulnerability that if that first user crashes or is disconnected in some other way we are left with a permanently locked row (requiring an Admin to detect the problem and then take action to reset the row).&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Just to comment on that: If you have to "clean up" data for lost connections/crashed applications, a &lt;A href="http://dcx.sap.com/index.html#sqla170/en/html/3bcac0a86c5f10148e469547933d58ff.html"&gt;Disconnect system event&lt;/A&gt; can be used to do so automatically, such as the sample from this FAQ:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://sqlanywhere-forum.sap.com/questions/24026/set-option-publicdisconnect_procedure"&gt;SET OPTION PUBLIC.disconnect_procedure&lt;/A&gt;&lt;/P&gt;
&lt;HR /&gt;
&lt;P&gt;That is, if you really need to "flag" the "start to edit" by the first updater and have to commit that (so other users see the modified flag), a Disconnect event should solve the problem of manually having to "clean up" that flag, particularly when you store the connection number of the according user, since the event can easily identify the connection number.&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 07:40:08 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842612#M4873455</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-07T07:40:08Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842613#M4873456</link>
      <description>&lt;P&gt;nice :). I particularly like the way it doesn't need any clearing up if the connection is lost (or the db crashes).&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 08:36:41 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842613#M4873456</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-08-07T08:36:41Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842614#M4873457</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;(or the db crashes)&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;OK, clean-up for that one is quite difficult to implement even with a "Disconnect" event...:) (Reminds me of the question about a missing "DatabaseShutdown" event, as opposite of the existing DatabaseStart event...)&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 09:56:23 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842614#M4873457</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-07T09:56:23Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842615#M4873458</link>
      <description>&lt;P&gt;Yes - clean-up code for these kind of things needs to go in a Database Start event as well as in Disconnect events. That's part of what makes Breck's solution so neat.&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 10:27:03 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842615#M4873458</guid>
      <dc:creator>justin_willey</dc:creator>
      <dc:date>2017-08-07T10:27:03Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842616#M4873459</link>
      <description>&lt;P&gt;Well, I'd still wonder if a user connection should really be blocked that long - what will the UI tell the user? &lt;EM&gt;"Please wait until user XY has finally done with that thing..."&lt;/EM&gt;, even if that may take several hours?&lt;/P&gt;
&lt;P&gt;For longer transactions, I guess it might be more reasonable to set option "blocking_timeout" to a small timespan (e.g. some seconds) and return the default blocking timeout error to the application so a user might do other work and try lateron (aka "polling" whether the row is still blocked), without blocking a connection for a long time... (All that would still work with Breck's scenario, without additional clean-up overhead.)&lt;/P&gt;
&lt;P&gt;But of course, that behaviour is application-specific, so only AIK can tell:)&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 10:48:50 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842616#M4873459</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-07T10:48:50Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842617#M4873460</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;what will the UI tell the user? &lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I know what the &lt;B&gt;user&lt;/B&gt; will say...&lt;/P&gt;
&lt;P&gt;&lt;IMG src="https://www.mememaker.net/static/images/memes/4548540.jpg" width="200" /&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 07 Aug 2017 14:59:06 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842617#M4873460</guid>
      <dc:creator>Breck_Carter</dc:creator>
      <dc:date>2017-08-07T14:59:06Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842618#M4873461</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;"DatabaseShutdown" event&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you could have that, could you also have a "Disembark" event?&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG src="http://big.assets.huffingtonpost.com/contrappppfalling.gif" width="300" /&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Mon, 07 Aug 2017 15:12:29 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842618#M4873461</guid>
      <dc:creator>Breck_Carter</dc:creator>
      <dc:date>2017-08-07T15:12:29Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842619#M4873462</link>
      <description>&lt;P&gt;Well... a DatabaseShutdown system event would be helpful for cleaning up a controlled shutdown, say, for saving the current cache contents in v17 or for other clean-up stuff...  Of course it would possibly not be callable when the database server crashes or when a database assertion appears... But I'm quite sure in most cases databases are shutdown intentionally and controlled.&lt;/P&gt;
&lt;P&gt;Of course part of such clean-up can be delayed for the next DatabaseStart event, however, properties as the former cache contents cannot.&lt;/P&gt;</description>
      <pubDate>Tue, 08 Aug 2017 03:33:01 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842619#M4873462</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-08T03:33:01Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842620#M4873463</link>
      <description>&lt;P&gt;Instead of the DatabaseShutdown event handler, I'd propose to design the application in the way that it can recover its data/state/what_should_be_cleaned when the DB starts.&lt;/P&gt;
&lt;P&gt;If the shutdown process is controlled, this event is not needed. If a crash happens, this event is not fired &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 08 Aug 2017 03:37:43 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842620#M4873463</guid>
      <dc:creator>Vlad</dc:creator>
      <dc:date>2017-08-08T03:37:43Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842621#M4873464</link>
      <description>&lt;P&gt;I'm probably the last person who should post a flippant Julie Andrews gif... Foxhound desperately needs what Volker suggests (a DatabaseShutdown event) but Vlad's reality intrudes: Foxhound must (try to) do everything in the DatabaseStart event.&lt;/P&gt;
&lt;P&gt;The point "in most cases databases are shutdown intentionally" certainly applies to embedded databases.&lt;/P&gt;</description>
      <pubDate>Tue, 08 Aug 2017 05:32:58 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842621#M4873464</guid>
      <dc:creator>Breck_Carter</dc:creator>
      <dc:date>2017-08-08T05:32:58Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842622#M4873465</link>
      <description>&lt;P&gt;Hi Volker,&lt;/P&gt;
&lt;P&gt;Thank you very much for your reply.  You have made me aware of capabilities that I did not know were in the server and they look very powerful.  Your first suggestion makes sense to me and it solves the problem of leaving the connection open for long period time.  I have studied the example in the link you gave me at SET OPTION PUBLIC.disconnect_procedure and I believe I understand it (I am new to setting up events and stored procedures so please bear with me) but one item is not clear.  Would you be so kind as to give me the syntax I would use in the handler to update the row to clear the connection ID that was initially set by the first user?&lt;/P&gt;
&lt;P&gt;Also, I find the MESSAGE TO CLIENT to be exciting because I never thought there would be a capability available to notify other users that the lock has been removed.  However, I don't understand how the client code actually receives the message (I am using embedded SQL) so could you clarify that please?&lt;/P&gt;
&lt;P&gt;Finally, your suggestion of using a mutex is interesting so I went to learn about that and I wonder if you would recommend that over defining the event?  Do you see any significant advantages or disadvantages for one approach or the other?&lt;/P&gt;
&lt;P&gt;Again, thank you very much for your help.&lt;/P&gt;</description>
      <pubDate>Tue, 08 Aug 2017 16:44:41 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842622#M4873465</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-08-08T16:44:41Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842623#M4873466</link>
      <description>&lt;P&gt;Hi Volker,&lt;/P&gt;
&lt;P&gt;The design I'm working towards allows the first user to access the road to have Write permissions.  Subsequent users may still open the row and view the data but they are notified that they will not be able to make any changes and save back to the database.&lt;/P&gt;</description>
      <pubDate>Tue, 08 Aug 2017 16:51:34 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842623#M4873466</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-08-08T16:51:34Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842624#M4873467</link>
      <description>&lt;P&gt;Hi Breck,&lt;/P&gt;
&lt;P&gt;Thank you for your extensive reply with the tests showing impact on the log.  However, I'm confused about a couple of points.  It seems you are suggesting that I use the default server locking when adding to the row the "signal to update intent" count without committing, but that was my original problem in that it would leave the transaction open for long period of time.It's obvious to me that there is something so that I do not understand about your suggestion.  Also, I don't understand what I would do with this count showing the number of clients that are interested in being able to update the row. If you could elaborate a bit further I would appreciate that very much.&lt;/P&gt;
&lt;P&gt;Thanks.&lt;/P&gt;</description>
      <pubDate>Tue, 08 Aug 2017 16:58:48 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842624#M4873467</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2017-08-08T16:58:48Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842625#M4873468</link>
      <description>&lt;P&gt;Well, I still do not understand how your users are informed about a writing conflict: Are they just informed that the desired row is currently "under construction" and therefore they cannot themselves modify it and then&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;they are told to "try later" (leaving it to them how they find out about when the row is available for modification) or&lt;/LI&gt;
&lt;LI&gt;they will get a notification as soon as the row is available again (if so, when several users wait for a row, who is the next who can lock the row?)?&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The default locking mechanism Breck has shown offers both ways:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;When the "blocking_timeout" is set to a small timespan (e.g. some seconds) and the row is still blocked, the request will return the default blocking timeout error, so you know your modification is currently not allowed, and you should try later. Your connection is not blocked, so you can do other work.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;When the "blocking_timeout" is set to 0, your request will wait until the current writer has committed his change, so your work (at least the current transaction) is suspended. (Of course you could use another connection to do separate work.)&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;In my understanding, in case the user should be informed automatically when the row is available again, that means any kind of DB-internal wait mechanism must be established (a blocked connection as with option 2, a WAITFOR MESSAGE, a wait for a mutex), and all those will require a worker to do the wait. There's no free lunch here. And therefore it seems that the default locking mechanism might be much easier to use than the other alternatives.&lt;/P&gt;</description>
      <pubDate>Wed, 09 Aug 2017 03:56:22 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842625#M4873468</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-09T03:56:22Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842626#M4873469</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;Would you be so kind as to give me the syntax I would use in the handler to update the row to clear the connection ID that was initially set by the first user? &lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Well, it would be the opposite of the UPDATE the user does to mark the row as "blocked". Enhancing Breck's sample wirh a "locked_by_userid" column, say the user would do the following:&lt;/P&gt;
&lt;PRE&gt;update t
   set locked_by_userid = connection_property('Number')
   where pkey = 1 and locked_by_userid is null;
commit;
-- Now the row is marked as locked for other users, but does not use a DB lock to do so, so the application need to behave accordingly...
... 
-- loooooong work...
-- finally mark row as available
update t
   set locked_by_userid = null
   where pkey = 1 AND locked_by_userid = connection_property('Number');
commit;
&lt;/PRE&gt;

&lt;P&gt;If the connection would die between marking the row as locked and as free, a disconnect event could handle this such as:&lt;/P&gt;
&lt;PRE&gt;create event EV_Disconnect
type "Disconnect"
handler
begin
   -- NOTE: Ommitting all reasonable debug messages and error handling here!
   if event_parameter('DisconnectReason') in ('abnormal', 'inactive') then
      update t
         set locked_by_userid = null
         where locked_by_userid = event_parameter('ConnectionID');
   end if;
end;
&lt;/PRE&gt;</description>
      <pubDate>Wed, 09 Aug 2017 04:11:13 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842626#M4873469</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-09T04:11:13Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842627#M4873470</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;Also, I find the MESSAGE TO CLIENT to be exciting because I never thought there would be a capability available to notify other users that the lock has been removed. However, I don't understand how the client code actually receives the message (I am using embedded SQL) so could you clarify that please?&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This is just a basic "inter-connection-communication" facility: One connection must use a WAITFOR ... AFTER MESSAGE BREAK statement and will wait until a message is received (or the maximum wait time has been reached), and the other connection must use a "MESSAGE TO CLIENT FOR ..." statement to notify the other(s) (and must usually know the other connection id beforehand). The exchanged information is just the message text, so it is not at all related to a particular database object/row/whatever, you need to use the message text to specify what is meant.&lt;/P&gt;
&lt;P&gt;For a basic understanding, see the &lt;A href="http://dcx.sap.com/index.html#sqla170/en/html/818048c76ce210148727b1a40f9a5d29.html"&gt;last sample in the v17 docs.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;With v17, in case you have to use somekind of IPC between two connections, I would highly recommend the use of &lt;A href="http://dcx.sap.com/index.html#sqla170/en/html/95fd05156ea11014ab3cefaf7344bda1.html"&gt;mutexes/semaphores&lt;/A&gt; over the MESSAGE TO CLIENT facility as they are easier to handle. (FWIW: While "mutexes" and "events" are both terms of OS level IPC facilities, an event in SQL Anywhere is something totally different, so a SQL Anywhere "mutex" is not meant to replace the event I have spoken about here!...) &lt;/P&gt;
&lt;P&gt;However, as stated in a new comment under Breck's answer, I still think its easiest to use the default blocking mechanism.&lt;/P&gt;</description>
      <pubDate>Wed, 09 Aug 2017 04:33:29 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842627#M4873470</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2017-08-09T04:33:29Z</dc:date>
    </item>
    <item>
      <title>Re: Need help designing a locking strategy</title>
      <link>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842628#M4873471</link>
      <description>&lt;P&gt;For the record, the update_count column is just a column that can be updated in order to obtain a write lock on the row. It has &lt;B&gt;no&lt;/B&gt; other purpose.&lt;/P&gt;
&lt;P&gt;Yes, the technique presented does start a long-running transaction, that is the point: use the standard locking mechanism to prevent other people from starting a update dialog if one is already in progress.&lt;/P&gt;
&lt;P&gt;A long-running transaction isn't necessarily evil, only if it has undesirable (and often unexpected) effects on other connections which is not the case here.&lt;/P&gt;
&lt;P&gt;Nothing prevents other users from selecting and displaying the row if the default isolation level 0 (dirty reads) is in effect.&lt;/P&gt;
&lt;P&gt;The technique can be enhanced to warn other users the row is being updated, instead of silently blocking them, as follows (using ISQL as the "application"):&lt;/P&gt;
&lt;PRE&gt;BEGIN -- simulated application code block

DECLARE @sqlcode   INTEGER;
DECLARE @errormsg  VARCHAR ( 32767 );

SET TEMPORARY OPTION BLOCKING = 'OFF';

BEGIN 
   UPDATE t
      SET update_count = update_count + 1
    WHERE pkey = 1;
EXCEPTION
   WHEN OTHERS THEN
      SELECT SQLCODE, ERRORMSG() 
        INTO @sqlcode, @errormsg;
      SET TEMPORARY OPTION BLOCKING = 'ON';
      IF @sqlcode = -210 THEN
         MESSAGE STRING ( 'Connection ', @@SPID, ' - Try again later: ', @errormsg ) TO CONSOLE;
         RETURN; -- return to caller
      ELSE
         RESIGNAL; -- return to caller with error
      END IF;
END;

-- Carry on...

SET TEMPORARY OPTION BLOCKING = 'ON';
MESSAGE STRING ( 'Connection ', @@SPID, ' - OK to continue with update' ) TO CONSOLE; 

END; -- simulated application code block

-- MESSAGE output written to dbsrv17.exe -o file:

Connection 1 - OK to continue with update
Connection 2 - Try again later: User 'dba' has the row in 't' locked
&lt;/PRE&gt;</description>
      <pubDate>Wed, 09 Aug 2017 13:05:39 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/need-help-designing-a-locking-strategy/qaa-p/13842628#M4873471</guid>
      <dc:creator>Breck_Carter</dc:creator>
      <dc:date>2017-08-09T13:05:39Z</dc:date>
    </item>
  </channel>
</rss>

