不用Redis来实现锁机制(不用redis做锁)
最近,由于Redis在缓存技术方面的迅速发展,它在实现锁机制方面越来越受到许多人的青睐。实际上,把Redis用作分布式锁也是很棒的选择,但是在某些特殊场景下,Redis 可能不是最佳的选择。所以不使用Redis也可以实现锁机制。
例如使用文件锁,比如有一个文件“unique.lock”,只要该文件存在,则表示希望对应的资源被锁定。此时,任何尝试访问该资源的程序都会检查是否存在该文件。如果存在,则会放弃锁定该资源,因为其他程序已经占用了该锁。用Python实现文件锁会如下:
import os
# 加锁def acquire_lock(lock_dir):
global lock_fd lock_path = lock_dir + '/unique.lock'
# 通过文件锁的Linux的open系统调用 order = os.O_CREAT | os.O_TRUNC | os.O_WRONLY
lock_fd = os.open(lock_path, order) # 阻塞式获取文件锁
os.lockf(lock_fd, os.F_LOCK, 0)
# 释放锁def release_lock():
# 释放文件锁 os.lockf(lock_fd, os.F_ULOCK, 0)
os.close(lock_fd)
另一种实现锁机制的方法是通过** 数据库 **操作实现,MySQL本身就提供了一个“SELECT … FOR UPDATE”语句,该语句会确认一行记录,以便事务可以更新它,而另一个事务无法在给定时间内更新。
使用MySQL实现数据库锁的具体实现如下:
# 加锁
def acquire_lock(): sql = "SELECT * FROM table WHERE X=Y FOR UPDATE"
# 执行sql语句 cur.execute(sql)
# 释放锁
def release_lock(): # 自动释放锁
conn.commit()
总体而言,上面两种方法不用Redis也可以实现锁机制,但有的优缺点:
* 文件锁实现起来比较简单,但不适合分布式环境;
* 数据库锁支持分布式,但是在一方面需要消耗大类资源,另一方面在高并发情况下,锁容易被占用。
因此,上面所阐述的锁机制都不是最佳选择,Redis作为更特殊的场景如分布式锁,其安全性、易用性和可靠性优势在对比中可见一斑。