数据库并发操作下的:排他锁(X),共享锁(S),死锁,活锁

xiaoxiao2021-02-28  18

丢失数据修改:两个事务T1,T2读入同一数据并进行修改,但只能保存最后执行事务的修改结果所以第一个事务修改的结果就自动后一个事务被覆盖!!!读“脏”数据:产生原因:数据在执行修改操作!例:两个事务T1,T2,事务T1执行的功能是对某一数据进行修改,而事务T2在T1执行过程中读取该修改后数据(此时T1还未将数据写回数据库中),但因某些原因T1修改数据失败,数据回滚!造成T2读到的值与数据库中的不一致(即产生脏数据)。不可重复读:事务T1先读取某个数据,即后T2对该数据进行修改操作,T1再重新读取时,所得结果不一致,造成不可重复读错误!另外产生幽灵数据也属于不可重复读范畴,即前后读取的数据不同,莫名多了(插入)或少了(删除)一些记录!为避免上述情况然后产生了:排他锁(X,写锁):某数据被T1加X锁,不再允许其他事务对其进行任何锁处理(直到T1释放X锁),仅有事务T1能对数据可读可修改,其他事务无读写权限;    共享锁(S,读锁): 只读,不能修改,即允许多个事务对某个数据同时获得S锁读权限,且无法添加X锁修改数据!封锁协议:1:一级封锁协议(T1,T2只做修改处理,不读取数据)-->T1:X锁,T2:X锁,对事务T1要修改的数据加X锁,直到T1事务结束再释放,T2再加X锁,优点:避免数据丢失修改;     2:二级封锁协议(T1做修改处理,T2读取数据)-->T1:X锁,T2:S锁,优点:不丢失数据修改,且不读“脏数据”,缺点:不可重复读(事务T1给数据加了X锁,T2此时无法执行读操作);       3:三级封锁协议-->T1:S锁,T2:X锁,优点:不丢失数据修改,不读“脏数据”,可重复读!活锁、死锁本质上是一样的:都是多个线程任务没有任何进展。原因是在获取共享资源时,并发多线程或多进程声明资源占用(即加锁)的顺序有冲突,死锁是加不上就死等(多线程都处于阻塞状态);活锁是加不上就放开已获得的资源重试,这种情况下线程并没有阻塞所以是活的状态,但是只是在做无用功(每次重试都是失败的),其实多核活锁不太常见(资源分配充足)。举个例子资源A和B,进程P1和P2start:P1 lock AP2 lock BP1 lock B fail context switchP2 lock A fail context switchP1 release AP2 release Bgoto start    (活锁,不断尝试,做无用功)防止死锁常用办法:1:一次封锁法:把第一个事务要用到的数据一次性加锁处理,缺点降低了系统的并发性!       2:顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序来操作,缺点不同事务的执行操作不同很难统一封锁顺序!
转载请注明原文地址: https://www.6miu.com/read-2650206.html

最新回复(0)