Locking and unlocking of PHP Redis

Source: Internet
Author: User
This article mainly introduced about PHP Redis locking and unlock, has a certain reference value, now share to everyone, have the need for friends can refer to

Php+redis implement lock and unlock operation

Business background : In room chess game need to use a lock to prevent the concurrent operation caused by the Redis data dirty read problem, such as adding the user into the room action:

In the case of concurrency, get roomusers will have a dirty read phenomenon;

Solution : Lock the room to achieve a room to allow only one client operation at a time, the other concurrent clients wait; that is-----blocking lock;

Locking : There are several types of Redis lock: incr, set, Setnx, Hsetnx, can refer to this article: several implementations of Redis plus lock

Here I use set this way

$roomId = $_get[' Roomid '); $user = $_get[' user '];             ' Zhang San ' $key = "lockroom:{$roomId}"; $value = $roomId. Uniqid (); $ex = 3;//If $key does not exist, the value of the set $key is $value and the validity period is 3s; Return True/falsewhile (TRUE) {    $res  = $this->redis->set ($key, $value, [' NX ', ' ex ' = + $ex]);    if ($res) {break;}    Usleep (5000);} Add user into Room $roomusers = $this->redis->get ("room:{$roomId}:users"); [' John Doe ', ' Harry '] $roomUsers [] = $user; $this->redis->set ("room:{$roomId}:users", $roomUsers); [' John Doe ', ' Harry ', ' Zhang San ']

unlock : After the operation of course to unlock, do not unlock at least to wait 3 seconds;
Unlock Delete key with delete; But there is a pit, not directly with the delete, because assuming that CLIENT01 acquired the lock, in the process of adding a user to enter the room for more than 3 seconds, this time client02 will also acquire the lock and set 3S, and then when the client01 operation is finished delete key, The client02 set lock is removed;
It is recommended to perform the removal with LUA code, because Lua execution is atomic.

Add user into Room $roomusers = $this->redis->get ("room:{$roomId}:users"); [' John Doe ', ' Harry '] $roomUsers [] = $user; $this->redis->set ("room:{$roomId}:users", $roomUsers); [' John Doe ', ' Harry ', ' Zhang San ']//lua script unlock//First determine if key is value, TRUE is deleted, so $value design to have random uniqueness $script = ' If Redis.call ("Get", keys[ 1] = = Argv[1]then    return redis.call ("Del", Keys[1]) Else    return 0end '; $this->redis->eval ($script, Array ($key, $value), 1);

You can also look at this article: Unlock the correct posture of the Redis lock

and the PHP Operation Redis Documentation: Phpredis contains the set (), eval () function explanation

Note: Using LUA scripts here php.ini requires Open shell_exec () and other system functions
The above code is only for reference!!

The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!

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.