I'm working with an Access 2007 frontend linked to an SQL Server 2008 R2 backend and have encountered what I think is strange locking behavior caused by even simple passthrough select queries. More concretely:
I have a passthrough query of the simple form "SELECT * FROM tbl_A". If I open this query in access (normal datasheet query view) and the table has sufficiently many records ( roughly > 100 records, I haven't experimented to find the precise bound), then I get a lock on that table in SQL Server for as long as I keep the query open. If I try to run an update query or something like that on the table it leads to a deadlock. Same thing happens if I open a continuous form which has this passthrough query set as the record source. Looking at the view sys.dm_tran_locks in SQL Server shows it is an IS lock on a data page... don't know if that helps. As soon as I click the "last record" button in Access to scroll to the end of the query or the form, the lock is cleared and my other processes can update the table again.
As far as I can see my form and/or query properties are set to their defaults (recordset type = dynaset, record locking = no locks). Based on the description of dynasets as e.g. given here: https://msdn.microsoft.com/en-us/library/bb188204.aspx I would expect it to load only small batches of data as required to fill the viewable area, without locking the server for any extended period of time. As the linked article says:
Because they work with only a few rows at a time, dynasets minimize the duration that read locks are held on the server. This allows other users to modify data without having to wait as long as is necessary for locks to clear.
Can anyone explain why the dynaset is not acting as expected?
I have seen several possible workarounds suggested, e.g.
- using NOLOCK hint (as suggested here MS Access holds locks on table rows indefinitely, but it seems NOLOCK is discouraged in general?)
- using a disconnected ADO recordset as recordsources for my forms
- pulling the data from the server into temp tables on the client side and basing the forms on those temp tables
- redesign the frontend, add restrictors etc so that forms never pull more than, say 100 records (would be a LOT of work and seems unsafe without having a guarantee that it will never lock with the specified number of records)
All of these suggestions either don't work for me or seem to have many other disadvantages and/or require a major rewrite of the frontend... What is the best way to get around this issue?