Reputation: 317
I've been searching for some time now in here and other places and can't find a good answer to why Linq-TO-SQL with NOLOCK is not possible..
Every time I search for how to apply the with(NOLOCK) hint to a Linq-To-SQL context (applied to 1 sql statement) people often answer to force a transaction (TransactionScope) with IsolationLevel set to ReadUncommitted. Well - they rarely tell this causes the connection to open an transaction (that I've also read somewhere must be ensured closed manually).
Using ReadUncommitted in my application as is, is really not that good. Right now I've got using context statements for the same connection within each other. Like:
using( var ctx1 = new Context()) {
... some code here ...
using( var ctx2 = new Context()) {
... some code here ...
using( var ctx3 = new Context()) {
... some code here ...
}
... some code here ...
}
... some code here ...
}
With a total execution time of 1 sec and many users on the same time, changing the isolation level will cause the contexts to wait for each other to release a connection because all the connections in the connection pool is being used.
So one (of many reasons) for changing to "nolock" is to avoid deadlocks (right now we have 1 customer deadlock per day). The consequence of above is just another kind of deadlock and really doesn't solve my issue.
So what I know I could do is:
But my problem is:
My thoughts are:
Upvotes: 4
Views: 3581
Reputation: 1063013
1: LINQ-to-SQL does indeed not allow you to indicate hints like NOLOCK
; it is possible to write your own TSQL, though, and use ExecuteQuery<T>
etc
2: to solve in an elegant way would be pretty complicated, frankly; and there's a strong chance that you would be using it inappropriately. For example, in the "deadlock" scenario, I would wager that actually it is UPDLOCK
that you should be using (during the first read), to ensure that the first read takes a write lock; this prevents a second later query getting a read lock, so you generally get blocking instead of deadlock
3: using the connection isn't necessarily a big problem (although note that new Context()
won't generally share a connection; to share a connection you would use new Context(connection)
). If seeing this issue, there are three likely solutions (if we exclude "use an ORM with hint support"):
TransactionScope
- it can be a connection level transaction) to specify the isolation levelIIRC there is also a way to subclass the data-context and override
some of the transaction-creation code to control the isolation-level for the transactions that it creates internally.
Upvotes: 2