原来很多人都不知道:分布式锁不是为了解决共享资源的安全问题,它只能解决共享资源的操作大致顺序访问问题!
观点:一般我们用分布式锁并不是为了解决共享资源的安全问题,它只是为了解决共享资源的大致顺序访问的问题。
先讲一下分布式锁的由来
业务背景是:我们同时要对一些共享资源做一些操作的时候,那么就需要保证“安全”
比如,A 和 B 两个人同时向 X 转账 100 元,这时候,X 应该是 200 元。
其实共享资源的操作互斥性,我们可以只用互斥资源去保证,比如
update set balance = balance + #{addprice}
where account = 'X' and balance = #{oldBalance}
这个操作基于共享资源去保证操作的 “安全”,不会出现 A、B 同时向 X 转账 100 元,X 只收到 100 元的问题。
然后,这时候有人就说了,那我同时有 1 万个人都给 X 转账会发生什么?会出现,1万个人执行这个操作的时候,X 一行数据本身进行互斥操作会进行卡住。
就是,我们是因为数据库的开销太大了,所以,我们会在前边加分布式锁,来让对共享资源的访问大致顺序。
重点:我们是因为共享资源支撑不了同时的共享操作,所以需要引入分布式锁,解决的是对共享资源访问的大致顺序问题。
分布式锁会用同一个共享资源吗
答案是否,
分布式锁,我们就是为了解决对同一个资源的共享访问问题。所以我们 100% 不会用同一个共享资源。如果用了同一个,那还有必要加分布式锁吗?直接用共享资源不就好了吗?用同一个共享资源去实现分布锁,没有意义。(如果你数据库实现了分布式锁,然后去控制对数据库的同一行数据的修改。如果是你的锁和对象不是同一个数据库,那么就不是同一个共享资源。如果你是同一个数据库,那么没有意义!!!)
常见的:我们一般对数据库的操作的前边有可能加 Redis 分布式锁。
共享资源和分布式锁的状态可以一致吗?
我们用分布式锁,一般会有两种锁,无论什么情况下,我们无法去保证,两个资源的状态一致性。
比如,共享资源是 数据库,锁用 Redis 实现。
无论如何,你都无法保证的 数据库 和 Redis 的状态一致,也就是 共享资源和分布时锁的状态一致性!
分布式锁安全不安全?
分布式锁要想绝对的安全,就分布式锁没有最大的锁的时间,是可以达到绝对的完全。(举例:你用 Redis 做分布式锁的时候不设置锁的过期时间)但是这个会导致一些异常情况下,没有完全释放锁,那么会导致共享资源无法再访问。
这里边的共享资源的操作时间和你的分布式锁的最大锁的时间,永远有一个比较的问题。
因为没有任何一个人能够保证,共享资源的操作时间一定可以在 某个时间点 执行完毕。那你分布式锁的最长的锁的时间是需要有一个固定值得。
就是你用一个不固定的值去比对一个固定的值,一定是不确定的结果。
所以,我们一般会把分布式设置有最大的过期时间,超过这个锁的最长时间,共享操作就不能在操作了。
关键来了:“共享操作不能再操作了” 这个在技术上也是特别难以实现的
实际应用怎么做?
锁设置最大超时时间 是为了保证一些异常情况下,没有释放锁,我们系统依然可以对共享资源的操作。
我想表达的,我们工作中用的分布式锁 99.99% 都是有可能不安全的锁。
但是我们一般都会对共享资源去排他性的操作,来保证共享资源的绝对安全。(比如数据库的锁、事务)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人