本文主要内容

1.transaction的可串行化

2.数据库并发带来的问题, dirty read, Nonrepeatable reads, Phantoms幻读

3.隔离级别和2中的问题

4. 悲观锁和乐观锁

5. 锁类型,DML锁,DDL锁,闩,手动锁和用户定义锁

 

什么是transaction可串行化

通常,不管数据库初态怎样,一个调度对数据库状态的影响都和某个串行调度相同,我们就说这个调度是可串行化的。

理想情况下,transaction就应该是可串行化的。 意思就是几个transaction同时执行和串行执行的结果应该是一样的。 所以,同时执行的时候,哪个先执行,哪个后执行无关。

 

例子, T1和T2都要更新2个值

T1, data1=data1*2, data2=data2*2

T2, data1=data1+1, data2=data2+1

 

比如当前要更新2个值, data1=0 and data2=10,

1)串行执行, 先T1,再T2,结果就是data1=1 and data2=21.

2)串行执行,先T2,再T1,结果就是data1=2 and data2=22.

3)如果交叉执行, T1先执行data1, 再T2执行data1, 再T2执行data2, 再T1执行data2, 结果就是1 and 22。

4)如果#3中交叉执行的顺序换一下, 那么结果就是2 and 21。

5)交叉执行, T1先执行data1, 再T2执行data1, 再T1执行data2, 再T2执行data2,  结果就是1 and 21。

6)交叉执行, T2执行data1, 再T1先执行data1, 再T2执行data2,  再T1执行data2, 结果就是2 and 22。

上面的调度中#5, $6执行的结果和串行执行的结果一样,所以调度#5, #6是可串行化的。

#3和#4执行结果和串行执行的结果不一样,所以调度#3,#4不是可串行化的。


为什么串行化如此重要?用一个例子说明

一个销售员在输入订单的时候,会计在记账。

1)比如销售员输入一个X公司的订单,但是还没提交,还在很x公司商量

2)会计查到所有还没结算的订单,谈后给X公司发去账单。

3)这时x公司决定减少订单数,销售再次修改,然后提交

4)但是错误的订单已经发送给x公司。

上面这个调度就是不可串行化的调度。所以数据库的任务就是通过同步机制,让并行事物的调度都是可串行化的。通过加锁来让销售员或会计的事物串行执行。保证并发操作调度正确性的方法:

  •    封锁方法:两段锁(Two-Phase Locking,简称2PL)协议
  •    时标方法
  •    乐观方法