Answered by:
Locking Issue - t-sql in Access 2010

Question
-
Fellow Accessors, I am running into a 3624 error, very randomly.
1 - Access 2010
2- GUI Access DB with no table and NO LINKED TABLES. It only connects to backend when it needs to and then closes connection.
3 - Backend Access Db with all of the tables and queries.
4 - Client DB setting is Record Locking selected, Shared on opening, Record Lock is No LOCK.
5 - All VBA code is using DAO.
I can see where it is occuring and it is 'RANDOMLY" occuring on a Insert. Here is the code:
set mydb = Opendatabase(networksharelocation,False)
mysql = "Insert into StatusHistory (ID, status_code) Select TOP 1 ID, 6 from Statushistory where ......."
mydb.Execute myssql
Someone obviously has something locked. I am a SQL DBA but do know the inner workings of Access. So, my question to you is even though the settings are Record Locking, can another t-SQL query do a page lock in Access even though I have Access settings as they are? I was expecting for single row logic with where clauses, it should just grab the row and not the page.
Notice that I am doing an Insert - not an update nor delete. But I am reading the same table I am going to insert to and I just cannot believe that this should be causing a problem. Another query would have to be causing this.
Thanks,
MG
- Edited by mg30 Friday, September 23, 2016 4:29 PM
Friday, September 23, 2016 4:24 PM
Answers
-
Well, I should point out that a page lock and a record lock are in THIS context the same thing!
The access data engine can ONLY lock a page during an update. When you turn on row locking, what the ACE engine does is FAKE the record locking by simply PADDING the size of the record to = a full page!
Since access is now forcing the record to be the same size as a page, then a page lock thus only contains one record and then “presto” we now have row locking without really having row locking.
I should point out that the result of the above feature can often result in MASSIVE bloating and file increasing for given data updates.
For example, I have a sample database of xx Megs in size. I run this SIMPLE code:
Dim rst As DAO.Recordset
Dim i As Long
Dim t As Single
Set rst = CurrentDb.OpenRecordset("contacts")
t = Timer
Me.Text1 = "working..."
DoEvents
Do While rst.EOF = False
rst.Edit
i = i + 1
rst!City = "ci " & i
rst.Update
rst.MoveNext
Loop
t = Timer - t
debug.print "done in " & t & " seconds"
Beep
AFTER running above code, the database is really MUCH the same size. (6.7 megs). If I turn on row locking, then the above grows by a WHOPPING 120 megs in size! So file goes from 6.7 megs to 126 megs!
So row locking really does not exist – if you turn the feature on then access just pads all records to the size of one page and continues using page locking.
But to answer your question? No difference between using a sql update or a recordset update does not change the page locking used. (and we now know that row locking and page locking are the SAME thing in the given context of this discussion).
edit: the real lesson here is that turning on row locking can result in MASSIVE file bloating and increasing of size for simple update code. The reason of course is the row locking setting forces Access to EXPAND and pad the record to = a page size.
Regards,
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
- Edited by Albert D. Kallal Tuesday, September 27, 2016 7:58 PM
- Marked as answer by mg30 Wednesday, September 28, 2016 1:38 AM
Tuesday, September 27, 2016 7:56 PM
All replies
-
AFAIK, Access doesn't have real row-level locking since it's a shared file-based database.
David
Friday, September 23, 2016 4:30 PM -
Ok. thanks David
MG
Friday, September 23, 2016 5:03 PM -
I don't know if it will make any difference, but you can try setting the locking in the BE.
Bill Mosca
www.thatlldoit.com
http://tech.groups.yahoo.com/group/MS_Access_ProfessionalsFriday, September 23, 2016 6:40 PM -
HI Bill,
IF BE means backend, I did. The locking is identical on both.
Thx
MG
Friday, September 23, 2016 8:33 PM -
Yes BE = back End.
The locking could be due to the fact that you are running a SELECT on the same table you are inserting into. Is it necessary to do a SELECT TOP? Maybe you can get the ID and put it into a variable, close the recordset and then run your insert.
Bill Mosca
www.thatlldoit.com
http://tech.groups.yahoo.com/group/MS_Access_Professionals
- Edited by Bill Mosca, MS MVP 2006-2016 Monday, September 26, 2016 6:23 PM
Monday, September 26, 2016 6:23 PM -
Hi Bill,
Thanks. We thought of that too but the locking is happening in other locations which are not doing Select like my example but direct inserts with variables. This was just one of the examples. The real problem we believe lies in the network latency tied to other people inserting. I am used to SQL where this type of things does not have the same issues and can be handle via row locking not page locking as well as isolation options.
We are going to put retry logic in the error handler that only retries for certain errors.
MG
Monday, September 26, 2016 7:56 PM -
It sounds like you are going in the right direction. It just might be network issues.
And by the way, Access does do row locking.
Bill Mosca
www.thatlldoit.com
http://tech.groups.yahoo.com/group/MS_Access_ProfessionalsMonday, September 26, 2016 8:18 PM -
HI Bill,
Many thanks. One more question though. Others have told me that that it does NOT do row locking. Below screen shot I found on another forum about this that indicates when it will escalate to page locks.
Access 2010 Help:
Open databases by using record-level locking
Makes record-level locking the default for the currently open database.
Clearing this check box makes page-level locking the default for the
open database. The choice you make applies to data in forms, datasheets, and code that uses a recordset object to loop through records. This option does not apply to action queries or code that performs bulk operations by using SQL statements.this makes me believe ANYTIME I uses t-sql with db.Execute "....." It will give me a page lock.
So, If I convert my t-sql EXECUTE to recordset logic (rs.update) would this go to record locking?
Thanks, MG
Tuesday, September 27, 2016 11:42 AM -
>So, If I convert my t-sql EXECUTE to recordset logic (rs.update) would this go to record locking?
Perhaps. But it might be no harder also convert your back-end to SQL Server, and in VBA continue to use DAO but with ODBC, or switch to ADO and OleDB.
David
Tuesday, September 27, 2016 11:52 AM -
HI David,
Totally agree. I am a SQL DBA and already have been pushing this towards a SQL solution. Unfortuantly that will be down the road. I in the past couple of decacdes, I also have built a couple of solutions with Access front end communicateing to SQL with oledb. Works well.
So, you think changing the t-sql to recordset updates "might or might not" fix this?
MG
Tuesday, September 27, 2016 11:55 AM -
>you think changing the t-sql to recordset updates "might or might not" fix this?
Yes and will require code changes on the same order of magnitude as migrating to SQL Server which _will_ fix it.
David
Tuesday, September 27, 2016 2:23 PM -
AgreedTuesday, September 27, 2016 2:55 PM
-
HI Bill,
Many thanks. One more question though. Others have told me that that it does NOT do row locking. Below screen shot I found on another forum about this that indicates when it will escalate to page locks.
Access 2010 Help:
Open databases by using record-level locking
Makes record-level locking the default for the currently open database.
Clearing this check box makes page-level locking the default for the
open database. The choice you make applies to data in forms, datasheets, and code that uses a recordset object to loop through records. This option does not apply to action queries or code that performs bulk operations by using SQL statements.this makes me believe ANYTIME I uses t-sql with db.Execute "....." It will give me a page lock.
So, If I convert my t-sql EXECUTE to recordset logic (rs.update) would this go to record locking?
Thanks, MG
Bill Mosca
www.thatlldoit.com
http://tech.groups.yahoo.com/group/MS_Access_ProfessionalsTuesday, September 27, 2016 4:18 PM -
thx Bill
MG
Tuesday, September 27, 2016 6:32 PM -
Well, I should point out that a page lock and a record lock are in THIS context the same thing!
The access data engine can ONLY lock a page during an update. When you turn on row locking, what the ACE engine does is FAKE the record locking by simply PADDING the size of the record to = a full page!
Since access is now forcing the record to be the same size as a page, then a page lock thus only contains one record and then “presto” we now have row locking without really having row locking.
I should point out that the result of the above feature can often result in MASSIVE bloating and file increasing for given data updates.
For example, I have a sample database of xx Megs in size. I run this SIMPLE code:
Dim rst As DAO.Recordset
Dim i As Long
Dim t As Single
Set rst = CurrentDb.OpenRecordset("contacts")
t = Timer
Me.Text1 = "working..."
DoEvents
Do While rst.EOF = False
rst.Edit
i = i + 1
rst!City = "ci " & i
rst.Update
rst.MoveNext
Loop
t = Timer - t
debug.print "done in " & t & " seconds"
Beep
AFTER running above code, the database is really MUCH the same size. (6.7 megs). If I turn on row locking, then the above grows by a WHOPPING 120 megs in size! So file goes from 6.7 megs to 126 megs!
So row locking really does not exist – if you turn the feature on then access just pads all records to the size of one page and continues using page locking.
But to answer your question? No difference between using a sql update or a recordset update does not change the page locking used. (and we now know that row locking and page locking are the SAME thing in the given context of this discussion).
edit: the real lesson here is that turning on row locking can result in MASSIVE file bloating and increasing of size for simple update code. The reason of course is the row locking setting forces Access to EXPAND and pad the record to = a page size.
Regards,
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
- Edited by Albert D. Kallal Tuesday, September 27, 2016 7:58 PM
- Marked as answer by mg30 Wednesday, September 28, 2016 1:38 AM
Tuesday, September 27, 2016 7:56 PM -
HI Albert,
Many thanks. Well, now it comes to inserts. Since the record does not exist yet, I would interpret that the Access engine would have to lock a page with data in order to make the insert?
Thks MG.
Tuesday, September 27, 2016 9:23 PM -
It depends on if the page is new or not for that incoming new record.
Not a bad question!
The answer is interesting.
Page locking is NOT used when adding these new records. And the reason is that since the new record does not YET exist in the database, then no need to lock the NEW page that is currently being filled up when adding those new records – the page not written out until its full of records but that don’t matter because the pages not yet saved so who cares since then the records don’t exist at this point in time (until the page is actually written to disk).
What this means is that adding (or appending ) new records into a NEW page means these new records are not EXPANDED to a page size and thus that huge bloat I talked about does not occur.
So for a record being edited, the expand occurs to one page size. And for starting inserts into an existing page, then again the record padding occurs. However, the instant we are adding new un-used pages, then records are not expanded in that new page since they don’t yet exist and thus don’t need to be locked and thus no need to be expanded.
Regards,
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
Tuesday, September 27, 2016 9:32 PM -
Many Thanks Albert.
MG
Wednesday, September 28, 2016 1:38 AM