数据库并发控制和隔离级别

数据库的并发操作带来数据的不一致性有 丢失修改,不可重复读,读脏数据。其中不可重复读有三种情况。另外两种为:事务T1按照一定条件读取了某些数据,T2删除了部分记录,T1再次按相同条件读取记录时,发现有数据莫名消失。事务T1按照一定条件读取了某些数据,T2插入了符合T1条件的数据,T1再次按照相同条件读数据时,发现莫名多出数据。这两种情况叫做幻影读。

T1

T2

T1

T2

T1

T2

read A=1

A=A+1

 

 

Write A

 

 

 

read A=1

A=A+1

Write A

 

read A

read B

C=A+B=2

 

 

 

read A

read B

C=A+B=3

 

 

 

   read A

A=A+1

Write A

 

 

read A=1

A=A+1

Write A

 

 

 

 

 

rollback

 

 

 

  read A=2

 

a丢失修改

b不可重复读

c读脏数据

所以需要封锁技术控制并发操作

锁类型:

X锁,写锁, 排他锁 ,exclusive locks用于数据写操作前进行锁定。 如果事务T对数据A加上X锁,就只允许事务T读取和修改数据A,其他事务不能对数据A再加任何锁,但可以读。直到事务T释放A上的锁才能

S锁,读锁, 共享锁 ,share locks 用于数据读操作前进行锁定。 如果事务T对数据A加上了S锁,事务T就只能读取数据A但不可以修改,其他事务可以再对数据AS锁执行读取操作,只要数据A上有S锁,任何事物都只能对其加S锁而不能加X锁修改。

封锁粒度和意向锁这里就不讨论了。

锁的持续时间:

在基于锁的并发控制中,隔离级别决定了锁的持有时间。"C"-表示锁会持续到事务提交。 "S" –表示锁持续到当前语句执行完毕。如果锁在语句执行完毕就释放则另外一个事务就可以在这个事务提交前修改锁定的数据,从而造成混乱。

隔离级别

写操作

读操作

范围操作 (...where...)

未授权读

S

S

S

授权读

C

S

S

可重复读

C

C

S

可序列化

C

C

C

由这两种锁组合形成的四种隔离级别也有叫封锁协议

一级封锁协议--未授权读取(Read Uncommitted)

事务T在修改数据A之前必须先对其加X锁,直到事务结束才释放X

假设AB初始都为1

T1

T2

T1

T2

T1

T2

Xlock A

A=A+1

Write A

commit

Unlock A

 

 

 

等待

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

read A

read B

C=A+B=2

 

 

 

read A

read B

C=A+B=3

 

 

 

 

 

  Xlock A

A=A+1

Write A

commit

Unlock A

 

 

Xlock A

A=A+1

Write A

 

 

 

rollback

Unlock A

 

 

 

 

   read A=2

 

a正确

b不可重复读

c读脏数据

其中c读脏数据是这样理解的, 事件T1对A加了排他锁,对数据A进行了修改,若事件T2对A申请锁,则会wait;若事件T2不对A申请任何锁,则即使A加对A加了排他锁,T2也会无视。 

二级封锁协议--授权读取(Read Committed)

一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后方可释放S 

T1

T2

T1

T2

T1

T2

Xlock A

A=A+1

Write A

commit

Unlock A

 

 

 

等待

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

Slock A

Slock B

read A

read B

C=A+B=2

Unlock A

Unlock B

 

 

 

等待

等待

Slock A

Slock B

read A

read B

C=A+B=3

Unlock A

Unlock B

 

 

 

 

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

 

Xlock A

A=A+1

Write A

 

 

 

 

 

rollback

Unlock A

 

 

 

 

等待

等待

等待

·

·

·

·

Slock A

read A

Unlock A

a正确

b不可重复读

c正确

三级封锁协议--可重复读取(Repeatable Read)

一级封锁协议加上事务T在读取数据A之前必须先对其加S锁,直到事务结束才释放。

T1

T2

T1

T2

T1

T2

Xlock A

A=A+1

Write A

commit

Unlock A

 

 

 

等待

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

Slock A

Slock B

read A

read B

C=A+B=2

 

Slock A

Slock B

read A

   read B

C=A+B=3

Unlock A

Unlock B

 

 

 

 

 

 

 

 

 

 

 

 

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

Xlock A

A=A+1

Write A

 

 

 

 

 

rollback

Unlock A

 

 

 

 

等待

等待

等待

·

·

·

·

Slock A

read A

Unlock A

a正确

b T1读操作是正确的

但是T1范围读是会出现幻影读的

c正确

三级锁的在使用范围条件的时候会发生幻影读

T1

T2

select count[id] from user where id>10

Slock id [id>10]

count[id]=0

commit

Unlock

 

 

 

select count[id] from user where id>10

Slock id [id>10]

count[id]=0

commit

Unlock

 

 

 

 

 

 

insert into user values [id=11]

commit

 

幻影读

两段封锁协议--序列化(Serializable)

对任何数据进行读写之前,必须对该数据加锁包括使用where的范围读。在释放一个封锁之后,事务不再申请和获得任何锁,只能继续释放锁,直到事务结束。

T1

T2

T1

T2

T1

T2

Xlock A

A=A+1

Write A

commit

Unlock A

 

 

 

等待

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

Slock A

Slock B

read A

read B

C=A+B=2

 

 

read A

   read B

C=A+B=3

Unlock A

Unlock B

 

 

 

 

 

 

 

 

 

 

 

等待

等待

等待

Xlock A

A=A+1

Write A

commit

Unlock A

 

Xlock A

A=A+1

Write A

 

 

 

 

 

rollback

Unlock A

 

 

 

 

等待

等待

等待

·

·

·

·

Slock A

read A

Unlock A

a正确

b正确--不带范围的操作

c正确

两段锁在使用范围操作的时候不会发生幻影读

T1

T2

select count[id] from user where id>10

Slock id [id>10]

count[id]=0

 

 

 

select count[id] from user where id>10

count[id]=1

commit

Unlock

 

 

 


 

等待

等待

等待

等待

等待

等待

insert into user values [id=11]

commit

 

正确


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值