Before learning the processing of concurrent processing in rails, let's take a quick look at the concept of concurrent processing.
In applications that have multiple processes that access the same database at the same time, this can happen because one process updates the rows in the database and makes the data held in another process obsolete. For example, A and B have extracted the same data from the database successively, and all made changes, then B will update their own changes to the database, and later, a will update their own changes back to the database, then will cover the changes made by B, when the second extraction of the database, see is a modified results, rather than their own.
One solution is to lock the updated table or row, preventing other programs from being updated or accessed, locking can completely avoid concurrent problems, often called pessimistic locks, but in Web projects this practice is not feasible because at the same point in time, many users may need to access data.
An optimistic lock does not replace the external performance of data locking, and checks to determine if a record has been modified before it is written back to the database. The implementation in rails is that each and every row contains a version number, and whenever the row is updated, the version number is incremented, and when you do an update in your program, the Active record checks the row and the version number of the model, If it does not match, the modification is discarded and an exception is thrown.
For any table that contains an integer field Lock_version, the optimistic lock is enabled by default, and you can initialize this field of the new row to 0, but if you forget, the Active record will be done for you.
Let's look at how to implement the optimistic lock, and we'll create a table named counters:
CREATE TABLE counters (
ID int not NULL auto_increment,
count int default 0,
lock_version int default 0,
p Rimary key (ID)
);
Then I create a row for the table, read the row into a different model, and try to update it,
Class Counter < ActiveRecord::Base
end
counter.delete_all
counter.create (: Count => 0)
count1 = Counter.find (: a)
Count2 = Counter.find (: a)
Count1.count + = 3
count1.save
Count2.count + 4
Count2.save
When we run the above code, we get an exception, and rails discards the count2 changes because it contains the dirty data.
If you use optimistic locks, you need to handle these exceptions in your program, or you can disable optimistic locks:
Activerecord::base.lock_optimistically = False
With regard to optimistic locks, you can refer to Martin Flower's "Enterprise application solutions and patterns" in one of the contents of the Concurrency and Work unit (Work) model, believing that there is a deeper understanding of the concurrency mechanism of rails.