精确匹配!=唯一搜索
https://zhuanlan.zhihu.com/p/433319764
https://zhuanlan.zhihu.com/p/29150809
https://juejin.cn/post/6931752749545553933
数据库读写问题分析
事务,具有ACID特征的一系列指令操作
读到脏数据是可能该数据只是一部分,也可能后来就会滚了
读读不会出现问题
读写,读的时候,读到了一半旧数据,读到了一半新数据,或者读到了完全的新数据,结果刚读完新数据被回滚
本来,要么全读旧数据,要么全读新数据
写写
- 某数据不存在,insert的时候发现存在(被别人insert了)
- 某数据存在,update的时候发现数据不存在(被别人delete了)
- 某数据存在,select的时候发现数据不存在(被别人delete了)
- 某数据存在,delete的时候发现数据不存在(被别人delete了)
1
单线程,一系列命令按序执行,不会出现问题
多线程,每个线程命令按序执行,多个线程间命令顺序不唯一确定,如果不同线程操作不同数据,没有问题,如果不同线程操作了相同数据,会有问题(此时,不同线程对同一数据的操作先后顺序是无法确定的,这一点由OS调度决定,这就是问题所在),就是多线程下对同一数据的读写问题
2
针对1中出现的问题,即数据库场景下的并发读写问题,有三条特定基础条件
- 就数据库而言,读即select,写即insert、update、delete
- 就数据库而言,真实数据存在和真实数据不存在都是一种“数据“,举例,因为id=1的数据不存在,可以insert,id=1的数据存在,可以delete,两者统称为对数据(id=1,可以理解为存在和不存在两种状态下id=1数据的消费)进行写(insert、delete)
- 数据库基本规则,有数据了就不能再插入了
- 就数据库而言,并发读写问题是由于两个线程对同一数据操作的语句先后顺序不确定导致的,那么就会出现四种情形,假设线程一的A语句与线程二的B语句对同一数据进行了操作,讨论B对A的影响:
- B执行完毕,A开始执行
- B正在执行,A开始执行
- A正在执行,B开始执行(这里有问题,直接就是无影响)
- A执行完毕,B开始执行(这里有问题,直接就是无影响)
如何评判B对A是否有影响:
初始状态
AB并发执行
再次查询数据,是否与只执行A得到的结果一致
以下会做一些简化
初始状态,数据存在时
- insert
- insert,无影响,insert必然失败
- update,无影响,insert必然失败
- select,无影响,insert必然失败
- delete,1)异常插入成功,2)无影响,3)无影响,4)无影响
- update
- insert,无影响,insert必然成功
- update,1)无影响,2)无影响,3)更新被覆盖,4)更新被覆盖
- select,1)无影响,2)无影响,3)无影响,4)无影响
- delete,1)异常找不到数据,2)异常找不到数据,3)无影响,4)无影响(更新数据被删除,不对,确实更新了)
- select
- insert,无影响
- update,1)查到了意料之外的新数据,2)查到了半旧半新数据,3)无影响,4)无影响
- select,无影响,纯粹读读
- delete,1)异常找不到数据,2)异常找不到数据,3)无影响,4)无影响
- delete
- insert,无影响
- update,无影响
- select,无影响
- delete,1)异常找不到数据,2)异常找不到数据,2)无影响,4)无影响
初始状态:数据不存在
- insert
- insert,1)插入失败,2)插入失败,3)无影响,4)无影响
- update,1)无影响,2)无影响,3)无影响,4)无影响(插入数据被覆盖)
- select,无影响
- delete,1)无影响,2)无影响,3)无影响,4)无影响(插入数据被删除,不对)
- update
- insert,1)异常更新成功,2)异常更新成功,3)无影响,4)无影响
- update,无影响
- select,无影响
- delete,无影响
- select
- insert,1)异常查到了数据,2)异常查到了数据,3)无影响,4)无影响
- update,无影响
- select,无影响,纯粹读读
- delete,无影响
- delete
- insert,1)异常删除了数据,2)异常删除了数据,3)无影响,4)无影响
- update,无影响
- select,无影响
- delete,无影响
分析以上结果
读对读
- 无影响,select对select无影响
读对写
- 无影响,select对insert、update、delete无影响
写对读
- 有数据
- update、delete对select有影响
- 无数据
- insert对select有影响
- 总结,insert、update、delete对select有影响
- 有数据
写对写
有数据
- insert、update对其他无影响
- delete对insert、update、delete都有影响
无数据
insert对insert、update、delete都有影响
delete、update对其他无影响
显然
- 写的不确定性会影响读的效果
- 可能会查到别的更新的数据(操作中(脏读),操作后(不可重复读))
- 可能本应有数据但是没有查到
- 可能本应没有数据但是查到了
- 写的不确定性会影响写的效果
- 有数据本应插入失败但数据不存在反而成功
- 有数据本应更新成功但发现数据不存在失败
- 有数据本应删除成功但发现数据不存在失败
- 无数据本应插入成功但数据存在导致失败
- 无数据本应更新失败但插入数据反而成功
- 无数据本应删除失败但插入数据反而成功
如果使用纯粹的读写锁必然可以保证数据库并发读写安全??
无数据没法加锁吧
问题?
好像直接使用读写锁就能解决安全问题
是由于需要并发才引入了其他么