I have a big SQL Server 2008 R2 database with many rows that are updated constantly. Updating is done by a back end service application that calls stored procedures. Within one of those stored procedures there is a SQL cursor that recalculates and updates data. This all runs fine.
But, our frontend web application needs to search through these rows and this search sometimes results in a
Lock request time out period exceeded. at
Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()..
After doing some research I have found that the best way to make this query to run without problems is to make it run with "read uncommitted isolation level". I've found that this setting can be made in the Telerik OpenAccess settings, but that's a setting that affects the complete database ORM project. That's not what I want! I want this level for this query only.
Is there a way to make this specific LINQ query to run in this uncommitted isolation level?
Or can we make this one query to use a WITH NOLOCK hint?
Use
SET LOCK_TIMEOUT -1
in the beginning of your query.
See the reference manual
Runnung the queries in read uncommitted isolation level (and using NOLOCK hint) can cause many strange problems, you have to clearly understand why do you do this and how it can interfere with your dataflow
Related
I heard that SQL Server SELECT statements causing blocking.
So I have MVC application with EF and SQL Server 2008 and it shares DB with another application which is very frequently writes some data. And MVC application generates some real-time reports based that data which comes from another application.
So given that scenario is it possible that while generating a report it will block some tables where another application will try to write data?
I tried to make some manual inserts and updates while report is generated and it handled fine. Am I misunderstood something?
This is one of the reasons why in Entity Framework 6 for Sql Server a default in database creation has changed:
EF is now aligned with a “best practice” for SQL Server databases, which is to configure the database’s READ_COMMITTED_SNAPSHOT setting to ON. This means that, by default, the database will create a snapshot of itself every time a change is made. Queries will be performed on the snapshot while updates are performed on the actual database.
So with databases created by EF 5 and lower, READ_COMMITTED_SNAPSHOT is OFF which means that
the Database Engine uses shared locks to prevent other transactions from modifying rows while the current transaction is running a read operation.
Of course you can always change the setting yourself:
ALTER DATABASE MyDb SET READ_COMMITTED_SNAPSHOT ON
READ UNCOMMITTED should help, because it doesn't issue shared locks on data that are being retrieved. So, it doesn't bother your other application that intensively updates the data. Another option is to use SNAPSHOT isolation leven on your long-running SELECT. This approach preserves data integrity for selected data, but for a cost of higher CPU, and more intense tempdb usage.
I'm currently running Microsoft SQL Express Server.
When one user performs a query without committing it, it locks the entire table.
The problem is that malicious users might "ruin" the database by doing so on purpose.
How can I prevent this from happening?
You need to understand database isolation levels http://en.wikipedia.org/wiki/Isolation_(database_systems). Most likely you are running queries as seralizable which will have that effect. Try submitting some code.
I'm developing an ETL application with batch processing. There is low (i.e. no) concurrency for updates. I'd like to avoid the overhead of granular locks and lock escalation by merely locking the entire table.
I'd like to avoid having to specify TABLOCK in every statement. Is there any way to set the locking granularity at the top of a stored procedure such that every statement automatically gets table locks on every table used? Shared or exclusive doesn't matter, though shared is preferred; the ETL will run overnight with no adhoc query load and prior to a batch of reports triggered when the ETL is complete.
Thanks!
You will need to take a look at Transaction Isolation Levels
To be honest though, I can't see why you need to be doing anything. I would have thought SQL Server would do a good enough job of locking by itself.
I have upgraded a set of databases from sql server 2000 to sql server 2008 and now large reads are blocking writes whereas this wasn't a problem in sql server 2000 (same databases and same applications & reports) Why? What setting in 2008 is different? Did 2000 default to read uncommitted transactions?
(update)
Adding with (nolock) to the report views in question fixes the problem in the short term - in the long run we'll have to make copies of the data for reporting either with snapshots or by hand. [sigh] I'd still like to know what about sql server 2008 makes this necessary.
(update 2) Since the views in question are only used for reports 'read uncommited' should be ok for now.
SQL Server 2000 did not use READ UNCOMMITTED by default, no.
It might have something to do with changes in optimizations in the execution plan. Some indexes are likely locked in a different order from what they were in SQL Server 2000. Or SQL Server 2008 is using an index that SQL Server 2000 was ignoring altogether for that particular query.
It's hard to say exactly what's going on without more information, but read up on lock types and check the execution plans for your two conflicting queries. Here's a nice short article that explains another example on why things can deadlock.
Read Committed is the default isolation level in SQL Server 2000, not Read Uncommitted.
http://msdn.microsoft.com/en-us/library/aa259216(SQL.80).aspx
I imagine that something in your app was setting the isolation level - perhaps via one of the connection object properties. Have a look here for the methods used to set Transaction Isolation levels via ADO, ODBC, and OLE DB.
You can do the same in SQL Server 2008, but...are you sure that your app should be running under read uncommitted? Is your app specifically designed to handle data movement and phantom reads?
I'm actually surprised that you didn't run into problems in SQL Server 2000. It seems like every week we were fixing stored procedures that were locking tables because someone forgot nolocks.
You could look into snapshot isolation, this will allow the app to read the older version of the rows whilst the writing threads are still busy updating the rows.
http://msdn.microsoft.com/en-us/library/ms189050.aspx
I have a database on ms sql 2000 that is being hit by hundreds of users at a time. There are intense reports using reporting services 2005 hitting the same database.
When there are lots of reports running and people using the database concurrently we see blocking processes to the level that the system starts to give time out to any transaction made after some time in that situation.
Is there a global way of minimize blocking so the transaction can continue to flow.
Use optimistic locking, if updates are not happening often and the database is mainly used for reporting.
SQL Server has quite a pessimistic locking default.
A look into SQL Server Table Hints might get you started.
The reports can use WITH(NOLOCK).
Other possibilities are having the reports run off a read-only replica of the database or running off a datawarehouse version of the database which is optimized for the reporting needs.
Since you are already using NOLOCK hints and READ UNCOMMITTED isolation level for your reports, the investigation needs to turn to the transactional queries coming in. This may get deep. Perhaps applications are keeping transactions open too long. It may also be the case that you have a lot of table scans or range scans in some of the other query volume, and those may be holding shared locks for long-running transactions. Those shared locks will block your writers.
You need to start looking at sp_lock, and seeing what kinds of locks are outstanding, see what locks the blocked queries are trying to obtain, and then examine the queries that are blocking the requestors.
This will help you if you are unfamiliar with SQL Server locking:
Understanding SQL Server 2000 Locking
Also, perhaps you could describe your disk subsystem. It may be undersized.
Thanks everyone for your support. What we do to mitigate the problem was to create a new database whit a logshipping procedure every hour to mantain in sync to the real one. The reports that do no need real time data where point to that database and the ones that needs real time data where restricted so only a few people can access them. The drawbacks whit the method is tha the data will be up to one hour out of sync and we need to create a new server for that purpose only. Also when the loggshipping procedure runs every connetion is drop for a very short period of time but it can be a problem to really long procedures or reports. After this I will verify the querys from the reports so I can understand what can be optimize. Thanks and I will recomend the site to the whole IT department.