Transactions and table locking

Hi,

Multi user ASP.Net website, SQL Server backend.

When using transactions to insert multiple rows into a table and then commiting them once you're happy that everything looks good, the table(s) gets locked before commiting.

Basically, I want to perform updates and inserts under a transaction but still allow other users to carry on using the site and potentially the tables that are being used with the transaction.

Question: Is there a way to stop the table lock occurring and for SQL to just do a record lock?, thus avoiding blocking other users?

I know that a possibility is to use Snapshot replication, but am a little worried about turning it on due to the small team we have for testing.

Many thanks,

Julian

September 3rd, 2015 11:14am

You want to lock the data waiting for the end user?  In that case you should not use database locking for this purpose.  It's something you would build into your application. 

One option is to add a "last update timestamp" column to your tables.  And when the user saves the data you open a transaction, check that the last update statement is still the same as when the data has been loaded, and then update the data and close the transaction.


  • Edited by Pygoc 15 hours 36 minutes ago
Free Windows Admin Tool Kit Click here and download it now
September 3rd, 2015 11:48am

Hi,

Hmmm, not sure I made my self clear then. 

The specific situation is this:

User 1: Uploads a file. Application extracts the data from the file and inserts it into the DB (under a Transaction). The application then validates the data that is stored in the DB (in various ways) to confirm that all is OK. Then the Commit happens if all is indeed OK.

User 2: Whilst User 1 is doing the above, User 2 should be able to carry on inserting, selecting, updating or whatever it is that they are doing.

Using normal Transactions, the tables will be locked whilst uploading, stopping User 2 from doing what they need to do.

User 2 will not have access to any of User 1 data. Just the same tables. Think - multiple Employers/Employees.

Julian

September 3rd, 2015 12:45pm

You want to lock the data waiting for the end user?  In that case you should not use database locking for this purpose.  It's something you would build into your application. 

One option is to add a "last update timestamp" column to your tables.  And when the user saves the data you open a transaction, check that the last update statement is still the same as when the data has been loaded, and then update the data and close the transaction.


  • Edited by Pygoc Thursday, September 03, 2015 3:30 PM
Free Windows Admin Tool Kit Click here and download it now
September 3rd, 2015 3:29pm

You want to lock the data waiting for the end user?  In that case you should not use database locking for this purpose.  It's something you would build into your application. 

One option is to add a "last update timestamp" column to your tables.  And when the user saves the data you open a transaction, check that the last update statement is still the same as when the data has been loaded, and then update the data and close the transaction.


  • Edited by Pygoc Thursday, September 03, 2015 3:30 PM
September 3rd, 2015 3:29pm

Hi GiantJulian,

In the default isolation level, read committed, your requirement is a typically scenario how this isolation level works, as long as your table has a unique index and not under a lock escalation.

User 1: Uploads a file and processes other actions within a transaction and that transaction won't commit or rollback  until everything is done or any error occurs.

User 2: While the User1's transaction is processing,User 2 should be able to carry on selecting, updating via a where like unqiueColumn=? and inserting a row that doesn't violate the unique constraint.

Using normal Transactions, the tables will be locked whilst uploading, stopping User 2 from doing what they need to do.
This might be due to nonexistence of a unique index ,a lock escalation or not specifying a where clause forementioned.

If you have any feedback on our support, you can click here.

Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 3:03am

Hi GiantJulian,

In the default isolation level, read committed, your requirement is a typically scenario how this isolation level works, as long as your table has a unique index and not under a lock escalation.

User 1: Uploads a file and processes other actions within a transaction and that transaction won't commit or rollback  until everything is done or any error occurs.

User 2: While the User1's transaction is processing,User 2 should be able to carry on selecting, updating via a where like unqiueColumn=? and inserting a row that doesn't violate the unique constraint.

Using normal Transactions, the tables will be locked whilst uploading, stopping User 2 from doing what they need to do.
This might be due to nonexistence of a unique index, not specifying a where clause forementioned or a lock escalation.

If you have any feedback on our support, you can click here.

September 4th, 2015 6:44am

Hi Eric,

Thanks for getting back to me. 

Are you saying that it's possible that a table lock does not have to happen?

I can confirm that the tables I am using all have unique Primary Key indexes using a simple ID (Identity Specification - Is Identity = Yes, Identity Increment = 1 etc.). They also have one or two indexes, usually one of which is clustered.

I have put some simple test code together to simulate the table lock on just one table when I go to update it. This test code in fact inserts a new row, so there is no where clause. 

Should it be possible to insert a new row without a table lock? What might cause the lock escalation you mentioned?

Can you help?

Regards,

julian

UPDATE:

I have created a simple table with an incrementing ID as a Primary Key, and one data field nchar(10). Starting a transaction, inserting a record and not commiting the Transaction, produces a table lock, until the Commit occurs.

Is this expected behaviour, and is there any way round it without using Snapshot Transactions?

Julian

Free Windows Admin Tool Kit Click here and download it now
September 7th, 2015 10:57am

OK, another update!

Don't spend any brain power on trying to help me, I'm just figuring some things out here. Will update one way or the other if I figure it out.

Thanks for your help so far...

Julian

September 7th, 2015 12:36pm

OK, thanks for your help. Eric, I think your statement about the non existence of a unique index on any select statement was the key. Once I started to implement these, things started to work without Snapshot Isolation. 

However

I couldn't get it working with one table in particualr, and although I could probably get it implemented in the new upload code (see user 1 and user 2 above), I would then have to think about the select statements throughout the rest of the website, to make sure they're not being blocked.

So my final question is:

Using the scenario above (User 1 uploading a file, user 2 browsing and using the website), do you think that Snapshot Isolation Transacition would be the way to go whilst uploading the file, AND is it reliable? I can't find people moaning about it on the web, and it looks as though it's been around for 10 years to mature, so I'm guessing it might be the way to go.

Any comments would be most appreciated.

Julian

Free Windows Admin Tool Kit Click here and download it now
September 9th, 2015 3:32pm

Hi GiantJulian,

Weather snapshot isolation is reliable depends on how reliability is defined in your application.

When saying uploading I believe you mean inserting rows into table(s). Insert action in a table with unique index holds exclusive locks on KEY and RID while a select without specifying a unique column would try to get a shared lock on RID, so the later select would have to wait. See more details on LOCKS in SQL Server if your have interest.

In you case, user1 uploading a file and user 2 browsing the website, read_committed isolation would be enough if user2 access other data with a unique column, conversely a "select * from your table" or "select * from your table where non-unique Column=..." would be blocked. I'm not sure how long would the uploading take, if a long time and there're some places in your application the later select statements are used, to achieve your requirement, snapshot should be used.


September 10th, 2015 10:23pm

Maybe the hint READPAST can meet it.

This hint skips locked rows.

Free Windows Admin Tool Kit Click here and download it now
September 10th, 2015 10:49pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics