ADO.Net vs ADO Record Locking - ado.net

I'm struggling to understand the differences between ADO and ADO.NET.
ADO "Classic" has different lock levels... I'm wondering now, what is the default lock level for ADO.NET? How would I open a connection as Batch Lock or Read Only.
What is the default behavior of ADO.NET? What sort of lock does it place on a MSSQL database when doing a .fill().

ADO.net uses an optimistic locking concurrency by default but you also have to look at what is happening on the SQL server.
Unless you specify a hint such as NoLock a shared lock will be issued. This is a lightweight lock that allows other transactions to read a resource but no other transactions to modify the data. This lock is released after the data is finished being read

Related

Is optimistic locking equivalent to Select For Update?

It is my first time using EF Core and DDD concepts. Our database is Microsoft SQL Server. We use optimistic concurrency based on the RowVersion for user requests. This handles concurrent read and writes by users.
With the DDD paradigma user changes are not written directly to the database nor is the logic handled in database with a stored procedure. It is a three step process:
get aggregate from repository that pulls it from the database
update aggregate through domain commands that implement business logic
save aggregate back to repository that writes it to the database
The separation of read and write in the application logic can lead again to race conditions between parallel commands.
Since the time between read and write in the backend is normally fairly short, those race conditions can be handled with optimistic and also pessimistic locking.
To my understanding optimistic concurrency using RowVersion is sufficient for lost update problem, but not for write skew as is shown in Martin Kleppmann's book "Designing Data-Intensive Applications". This would require locking the read records.
To prevent write skew a common solution is to lock the records in step 1 with FOR UPDATE or in SQL Server with the hints UPDLOCK and HOLDLOCK.
EF Core does neither support FOR UPDATE nor SQL Server's WITH.
If I'm not able to lock records with EF Core does it mean there is no way to prevent write skew except using Raw SQL or Stored Procedures?
If I use RowVersion, I first check the RowVersion after getting the aggregate from the database. If it doesn't match I can fail fast. If it matches it is checked through EF Core in step 3 when updating the database. Is this pattern sufficient to eliminate all race conditions except write skew?
Since the write skew race condition occurs when read and write is on different records, it seems that there can always be a transaction added maybe later during development that makes a decision on a read. In a complex system I would not feel safe if it is not just simple CRUD access. Is there another solution when using EF Core to prevent write skew without locking records for update?
If you tell EF Core about the RowVersion attribute, it will use it in any update statement. BUT you have to be careful to preserve the RowVersion value from your data retrieval. The usual work pattern would retrieve the data, the user potentially edits the data, and then the user saves the data. When the user saves the data, you would normally have EF retrieve the entity, update the entity with the user's changes, and save the updates. EF uses the RowVersion in a Where clause to ensure nothing has changed since you read the data. This is the tricky part- you want to make sure the RowVersion is still the same as your initial data retrieval, not the second retrieval used to update the entity before saving.

JPA: LockModeType.NONE

Am I right with following ?
JPA: LockModeType.NONE means:
There is no explicit locking on JPA level / application layer
In the absence of explicit locking on JPA level, the application will use implicit locking
Implicit locking means, JPA is delegating the whole locking responsibility to the database system
If the database system has as default islation level, for example Committed Read, so JPA-LockModeType.NONE will cause that transactions will be handled as Committed Read
So, JPA-LockModeType.NONE is not the same as Uncommited Read because no database system has Uncommited Read as default, and it's also a little misleading because a database system always uses locks even with Uncommited Read.
is this correct ?

FireDAC: Shared Lock on Table with Firebird

I'm using Delphi 10.1 with FireDAC to connect to Firebird.
I would like to open a table in Exclusive mode in Firebird with FireDAC?
How would it be?
Firebird does not handle table or row locks. So there's no way you're going to get this to work with FireDAC... no connection parameters can do this magic.
What you can do with Firebird is to use the entire database in single user mode. To do this, you must shut it down, run GFIX to flag it as a single user database, and then reconnect to the database. You can find more details on the Firebird How-To FAQ. But I doubt this is what you are looking for.
You should explain better what you are trying to do. With real SQL servers you should not feel the need to lock tables or rows. Transactions and transaction isolation should be enough to handle most situations. If not, then you should probably start thinking about application level locks, that is, if you have just one application that uses the database.

How to get a connection and hold it using DAAB?

I have a task ahead of me that requires the use of local temporary tables. For performance reasons I can't use transactions.
Temporary tables much like transactions require that all queries must come from one connection which must not be closed or reset. How can I accomplish this using Enterprise library data access application block?
Enterprise Library will use a single database connection if a transaction is active. However, there is no way to force a single connection for all Database methods in the absence of a transaction.
You can definitely use the Database.CreateConnection method to get a database connection. You could then use that connection along with the DbCommand objects to perform the appropriate logic.
Other approaches would be to modify Enterprise Library source code to do exactly what you want or create a new Database implementation that does not perform connection management.
Can't see a way of doing that with DAAB. I think you are going to have to drop back to use ADO.Net connections and manage them yourself, but even then, playing with temporary tables on the server from a client-side app doesn't strike me as an optimal solution to a problem.

Why does entity framework uses “set transaction isolation level read committed” and what does this mean?

I am using Entity Framework, and I have tracked SQL Server using SQL Server Profiler. And I found that when I query the database using EF, the SQL Profiler will show the following:
set transaction isolation level read committed.
So what does this mean?
You should check the wiki about isolation levels. I guess you know transactions a little bit, the SaveContext() saves the changes in a transaction. There are several transaction levels, with increasing error filtering capabilities and decreasing performance. It is a good task to find the balance between safety and performance.
The read committed transaction level protects you from "dirty reads", but doesn't protect from "non-repeatable reads" and "phantom reads" (see wiki). Kinda deep topic, but you shall go through it once you plan to create more complicated and safe systems.
You can modify the transaction level like it is written here. But for basic applications you won't need this.