Database-based distributed locks

Source: Internet
Author: User

Usage Scenarios:A large-scale Web site deployment is distributed, the order system has three servers in response to user requests, the order is generated unified into the Order_info table; The Order_info table requires that the order ID (order_id) must be unique, so the three servers work together to confirm Order_ What is the uniqueness of the ID? The distribution lock will be used. Requirements for distributed locks:After understanding the usage scenario, take a look at what distributed locks we need (in the case of method locks) This lock is best to be reentrant (to prevent deadlocks) it is better to have a blocking lock (depending on the business considerations if this is required) there is a high availability lock and release lock function to obtain lock and release lock performance better Implementation method:The implementation of distributed locks is divided into 3 kinds, database-based, cache-based and zookeeper-based. Next we implement these three ways. database-based distributed locks:Approximate principle: Create a lock table directly, and when you want to lock a method or resource, add a record to the table and delete the record when you want to release it.
CREATE TABLE ' Methodlock ' (  ' id ' int (one) not NULL auto_increment COMMENT ' primary key ',  ' method_name ' varchar (UP) NOT NULL DEFAULT ' COMMENT ' Lock method name ',  ' mydesc ' varchar (1024x768) NOT NULL COMMENT ' Memo info ',  ' update_time ' timestamp not null DEFA ULT current_timestamp on UPDATE current_timestamp,  PRIMARY key (' id '),  UNIQUE KEY ' uidx_method_name ' (' Method_ Name ') USING BTREE) Engine=innodb DEFAULT Charset=utf8;

When we want to lock a method, execute the following sql:

Insert into Methodlock (METHOD_NAME,DESC) VALUES (' specific method name ', ' description ');

There are several issues with the simple implementation above:

1, this lock depends on the availability of the database, if the database is a single point, once hung, it will cause the business system is not available, 2, the lock does not have a failure time, once the unlock operation fails, the lock will persist in the database, other threads can not obtain the lock; 3, the lock can only be non-blocking,  Because the insert operation of the data will be error-free once the insertion fails, the thread that does not get the lock will not enter the queue, and the attempt to acquire the lock again will trigger the lock operation again; 4. The lock is non-reentrant, and the same thread cannot obtain the lock again until the lock is released, because the data already exists in the table. Of course, the above problems can be solved: 1, single point, two databases, two-way synchronization, once hung off to switch to another, 2, the expiration time, do a scheduled task, how often to clean up the timeout data, 3, non-blocking problems, the program writes for The Loop multiple attempts, until the lock is obtained; 4, non-reentrant, Add a field, record to get the IP and thread information, the next time if there is a query, then directly to the lock; Example code:Get Lock:
public Boolean lock () {        int result = 0;        try {            result = Jdbctemplate.update ("INSERT into Methodlock (METHOD_NAME,MYDESC) VALUES (?,?)", New object[]{" Com.wzy.home.study.distributedlock.MyResources.getNextId () "," Get OrderID "});        catch (Exception e) {            //todo nothing        }        if (result = = 1) {            return true;        }        return false;    }

Release Lock:

public Boolean UnLock () {        int rows = jdbctemplate.update ("Delete from methodlock where method_name =?", New object[]{"C Om.wzy.home.study.distributedlock.MyResources.getNextId () "});        if (rows = = 1) {            return true;        } else {            return false;        }    }

Two threads, simulating two clients for testing:

public void Testlock () {Thread T1 = new Thread (new Runnable () {@Override public void run () {                Boolean flag = Mysqllock.lock ();                    if (flag) {//has lock int orderId = Myresources.getinstance (). Getnextid ();                    System.out.println ("T1 get the lock, get the Order ID:" +orderid);                    try {thread.sleep (5000);                    } catch (Interruptedexception e) {e.printstacktrace ();                    } System.out.println ("T1 release lock");                Mysqllock.unlock ();        }            }        });                    Thread t2 = new Thread (new Runnable () {@Override public void run () {try {                Thread.Sleep (500);                } catch (Interruptedexception e) {e.printstacktrace ();            } trylock (); }//Multiple attempts to acquire the lock private BoOlean Trylock () {Boolean flag = Mysqllock.lock ();                    if (flag) {int orderId = Myresources.getinstance (). Getnextid ();                System.out.println ("T2 get lock, get Order ID:" +orderid);                    }else {System.out.println ("T2 acquires lock failed, try again");                    try {thread.sleep (1000);                    } catch (Interruptedexception e) {e.printstacktrace ();                    } trylock ();                Mysqllock.unlock ();            } return flag;        }        });        T1.start ();        T2.start ();            try {t1.join ();        T2.join ();        } catch (Interruptedexception e) {e.printstacktrace (); }    }

Output Result:

T1 get the lock, get the order ID: 1t2 failed to get the lock, try again T2 to get the lock failed, try again T2 get lock failed, try again T2 get lock failed again, try T2 get lock again failed, try T1 release lock again T2 get lock, get Order ID: 2 can see, It is true that T2 et T1 release the lock before getting the lock for business operations.

Database-based distributed locks

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.