when user opens edit form for some entity, I would like to LOCK this entity and let her make any changes. During editing she needs to be sure that nobody else does any edit operations on it.
How can I lock an entity in Entity Framework (C#) 4+, database MS SQL Server 2008?
Thank you so much in advance!
Bad idea, especially if you have many concurrent users. You will be killing scalability if you lock the rows in the database.
It is better to detect whether others have made edits and if so, inform the user and let them decide what to do.
The timestamp/rowversion data type is a good choice for a field to find out if any changes were made to a row data.
There are two ways to handle these situations:
Optimistic concurrency where you allow concurrent edits and inserts and catch exception if something violates concurrency rules. Optimistic concurrency is enforced by unique constraints guarding inserts of the same items and by timestamps / row version columns guarding concurrent updates to the same item. If somebody else updates row when current user is making changes the application will throw OptimisticConcurrencyException during saving and you will have to allow user to either overwrite other changes or reload new stored data.
Pessimistic concurrency where the record is locked for the duration of the operation executed by any client preventing other clients to update the same record. Pessimistic concurrency is usually enforced by custom columns added to your tables like LockedBy, LockedAt, etc. Once these columns are filled nobody else can select the record for edit. LockedAt can help you implement some automatic expiration of issued locks. Long running "EF transactions" are not long running database transactions.
Your initial description leads to second scenario which makes sense in some applications.
Related
Does a transaction lock my table when I'm running multiple queries?
Example: if another user will try to send data in same time which I use transaction, what will happen?
Also how can I avoid this, but also to be sure that all data has inserted successfully into database?
Begin Tran;
Insert into Customers (name) values(name1);
Update CustomerTrans
set CustomerName = (name2);
Commit;
You have to implement transaction smartly. Below are some performance related points :-
Locking Optimistic/Pessimistic. In pessimistic locking whole table is locked. but in optimistic locking only specific row is locked.
Isolation level Read Committed/Read Uncommitted. When table is locked it depends upon on your business scenario if it allowed you then you can go for dirty read using with NoLock.
Try to use where clause in update and do proper indexing. For any heavy query check the query plan.
Transaction timeout should be very less. So if the table is locked then it should throw error and In catch block you can retry.
These are few points you can do.
You cannot avoid that multiples users load data to the database. It is neither feasible nor clever to lock every time a single user requested the usage of a table. Actually you do not have to worry about it, because the DB itself will provide mechanism to avoid such issues. I would recommend you reading into ACID properties.
Atomicity
Consistency
Isolation
Durability
What may happen is that you could suffer a ghost read, which basically consist that you cannot read data unless the user who is inserting data commits. And even if you have finished inserting data and do not commit, there is a fair chance that you will not see the changes.
DDL operations such as creation, removal, etc. are themselves committed at the end. However DML operation, such as update, insert, delete, etc. are not committed at the end.
sorry for my bad english. I approached recently to programming in Visual C # and am not a expert programmer. After this short introduction, the important thing I need to implement a management competition on a record during editing operations. This means that having two computers at the same time using this software, the first that starts editing a record, have to "lock" the record so when and if, in the second instance of the program, an attempt to change the same record, a standard message will be displayed and the procedure is interrupted.
I actually use MySQL DBMS and the only thing I could do is to lock the record with "START TRANSACTION" until I COMMIT or close the connection. The problem is that I don't know how to check if there is an active transaction or some kind of block to stop the procedure and this means that the second instance of the program is completely blocked until they release the records from the first instance. Solutions? Thank you for your attention.
Well, in general it's a bad design to physically lock a record while a user is working on it. Database locks are supposed to be short. There should be only code execution between starting the transaction and committing it, but absolutely no user interaction.
You can google "Optimistic locking vs. Pessimistic locking" to understand more about the subject.
If you must use pessimistic locking, you will have to implement some sort of a smart software locks instead of database locks. For example, you could add two fields for the Current_Edit_By and Current_Edit_Time. When a user start editing a record, you fill in these fields with the user id and the current datetime. When another user try editing the same record, you check these two fields and if there are values there then you display an error.
Of course you will need to implement a mechanism to clean locked record automatically if the user disconnect from the database without committing the record. Hence the datetime field (To clear locks older than 30 minutes for example, as long as the connection is no longer there).
A while ago, I wrote an application used by multiple users to handle trades creation.
I haven't done development for some time now, and I can't remember how I managed the concurrency between the users. Thus, I'm seeking some advice in terms of design.
The original application had the following characteristics:
One heavy client per user.
A single database.
Access to the database for each user to insert/update/delete trades.
A grid in the application reflecting the trades table. That grid being updated each time someone changes a deal.
I am using WPF.
Here's what I'm wondering:
Am I correct in thinking that I shouldn't care about the connection to the database for each application? Considering that there is a singleton in each, I would expect one connection per client with no issue.
How can I go about preventing the concurrency of the accesses? I guess I should lock when modifying the data, however don't remember how to.
How do I set up the grid to automatically update whenever my database is updated (by another user, for example)?
Thank you in advance for your help!
Consider leveraging Connection Pooling to reduce # of connections. See: http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx
lock as late as possible and release as soon as possible to maximize concurrency. You can use TransactionScope (see: http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx and http://blogs.msdn.com/b/dbrowne/archive/2010/05/21/using-new-transactionscope-considered-harmful.aspx) if you have multiple db actions that need to go together to manage consistency or just handle them in DB stored proc. Keep your query simple. Follow the following tips to understand how locking work and how to reduce resource contention and deadlock: http://www.devx.com/gethelpon/10MinuteSolution/16488
I am not sure other db, but for SQL, you can use SQL Dependency, see http://msdn.microsoft.com/en-us/library/a52dhwx7(v=vs.80).aspx
Concurrency is usually granted by the DBMS using locks. Locks are a type of semaphore that grant the exclusive lock to a certain resource and allow other accesses to be restricted or queued (only restricted in the case you use uncommited reads).
The number of connections itself does not pose a problem while you are not reaching heights where you might touch on the max_connections setting of your DBMS. Otherwise, you might get a problem connecting to it for maintenance purposes or for shutting it down.
DBMSes usually use a concept of either table locks (MyISAM) or row locks (InnoDB, most other DBMSes). The type of lock determines the volume of the lock. Table locks can be very fast but are usually considered inferior to row level locks.
Row level locks occur inside a transaction (implicit or explicit). When manually starting a transaction, you begin your transaction scope. Until you manually close the transaction scope, all changes you make will be attributes to this exact transaction. The changes you make will also obey the ACID paradigm.
Transaction scope and how to use it is a topic far too long for this platform, if you want, I can post some links that carry more information on this topic.
For the automatic updates, most databases support some kind of trigger mechanism, which is code that is run at specific actions on the database (for instance the creation of a new record or the change of a record). You could post your code inside this trigger. However, you should only inform a recieving application of the changes, not really "do" the changes from the trigger, even if the language might make it possible. Remember that the action which triggered the code is suspended until you finish with your trigger code. This means that a lean trigger is best, if it is needed at all.
One of my co-workers is building a C# windows app that needs to grab a set of data and then row-by-row alter that data. If the system encounters a problem at any step in the process, it needs to roll back all of the changes.
The process he has created works well when dealing with smaller sets of data, but as soon as the number of rows get larger, it starts to puke.
The process of altering the data needs to happen in the windows app. What is the best way to handle large data changes atomically in a windows app?
Thank you.
Edit-
We are using a background thread with this process.
I apologize - I don't think I articulated the quandary we're in. We are using transactions right now with the system, I don't know if we're doing it effectively, so I'll definitely review the notes below.
We were thinking that we could spin off additional worker threads to get the work done more quickly, but assumed we would lose our atomic capabilities. Then we were thinking that maybe we could pull all the data into a data table, make changes in that object and then persist the data to the database.
So I was just going to see if someone had a brilliant way to handle this type of situation. Thanks for the comments so far.
I would suggest that you take a look at .NET's transactional model.
Here is some additional reading that may be helpful as well:
Writing a Transactional Application
Doing Transactions in C# and ADO.NET
As the problem is not well detailed in this question, I have to presume the "Is it plugged in?" type of question.
If you haven't done so already, potentially long-running operations should be spun off into their own separate BackgroundWorker thread, rather than blocking the UI thread.
We had a similar situation in dealing with mass updates of a large database. The solution we used was:
Step through each record in database. If it needs updating, create a dummy record with a new primary key.
Update the dummy record from the original, including the originals' PK in the dummy.
When you have created dummy records for all updates, lock the database and replace all foreign keys of the updated records with the primary key of the dummy records. Unlock the database.
Delete all records with the old primary keys.
Note this technique works best if there is only a single reference to the primary key.
I wrote a multi user app in c# some time age using SQL Server 2005 express as back-end.
I have a Orders collection. In order to use this class you would need to instantiate it and just call the Load(CustomerCode) method in order to populate the collection with the specified customers`s orders.
My question:
How do I enforce concurrency, so that only 1 user can request a Orders collection for a specific customer? When the user is done with the object(when the object is set to null),
I will need to make it available again.
You need to implement the Pessimistic Offline Lock pattern.
Essentially you have a table that you put records in that represent a "lock" on records in other tables. When you want to edit a record, you check to see if there's a lock in the lock table first, and react accordingly in your domain logic/UI.
It doesn't have to be a database, it could be an in-memory cache. When I say "table" in my example, I mean a logical table, not necessarily a database one.
Pessimistic Offline Lock prevents
conflicts by avoiding them altogether.
It forces a business transaction to
acquire a lock on a piece of data
before it starts to use it, so that,
most of the time, once you begin a
business transaction you can be pretty
sure you'll complete it without being
bounced by concurrency control.