## Problem description: An e-commerce platform launches a new mobile phone. Each person is limited to purchase 2 units, and it is expected that there will be 10W concurrency. In this case, if the inventory is deducted, it is guaranteed not to be oversold.Solution 1Use the database lock mechanism to record the Lock and then operate
SELECT * from goods where ID =1 for update; UPDATE goods set stock = stock - 1;Use exclusive locks to convert parallel operations into serial operations, but the performance and user experience of this solution are poorSolution 2 Use redis to implement distributed locks. Use the setnx command (when the key does not exist, create and set the value and return 1, when the key exists, it will return 0) to obtain the lock. In the business logic, we can Operate through such a plan
Jedis client = jedisPool.getResource(); while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){ Thread.sleep(10000); } //coding here client.del("lock")Advanced plan twoConsidering the deadlock problem, that is, after ready-made A acquires the lock, it crashes, resulting in the lock being unable to be released. We can use get The command obtains the timestamp of the lock, uses it to determine the timeout, and releases it
Long TIMEOUT_SECOUND = 120000L; Jedis client = jedisPool.getResource(); while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){ Long lockTime = Long.valueOf(client.get("lock")); if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) { client.del("lock"); } Thread.sleep(10000); } ........................... ........................... client.del("lock")Option 2 EnhancementIn the algorithm of Option 2, in order to ensure that in non-timeout situations, the lock can only be To release the locked thread, you can spell the thread signature
Long TIMEOUT_SECOUND = 120000L; String featureCode = "machine01"; Jedis client = jedisPool.getResource(); while(client.setnx("lock",featureCode+":"+String.valueOf(System.currentTimeMillis())) == 0){ Long lockTime = Long.valueOf(client.get("lock").substring(9)); if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) { client.del("lock"); } Thread.sleep(10000); } ........................... ........................... if (featureCode.equals(client.get("lock").substring(0, 8))) { client.del("lock"); }
in the timestamp of value. For more Redis related technical articles, please visit Redis Tutorial column to study!
The above is the detailed content of How redis implements distributed transactions. For more information, please follow other related articles on the PHP Chinese website!