【数据库】 并发 concurrency

 

1.Question

当数据库中多个transactions 同时进行时,会出现问题:

1)脏读 dirty read: W-R

2)不可重读 unrepeatable read:R-W

3)重写 :W-W

总结起来,就是只要有transaction在写,并发了另一个transaction就很危险。

例子:

T1 read A,看到A=1,

T2 write A,让A从1变为2,

T1 read A,发现A竟然不为1了(不可重读),这就发生了不可重读。

 

2. Solution

给访问的对象(数据库,表,等等)加锁。

 

方式1. 二相锁2PL(2 phase lock)

在读数据前,获得S锁; 在写数据前,获得X锁 (get SL before read,get XL before write)。

如果对象已经加了锁:如果是S锁,可以获得S锁,不能获得X锁;如果是X锁,不能获得任何锁。

这样做的结果:serializable, 事务互不影响

问题:死锁

解决办法:为事务加时间戳(timestamp,决定优先级)。way1,求锁的退出(如果优先级低);way2,求锁的trans等待,有锁的trans退出(如果优先级低)

3.Improvement

问题:并发性差 (如果把锁加在整个数据库,那么A在写,没有别的事务能同时访问了)。

解决:细分锁的范围和类型 (不锁整个数据库,只锁表、记录...)。

1)层级锁 hierarchical lock,意向锁 intention lock

优点:加大并发性

缺点:锁的数量增加,计算开销增加

产生问题:幻读 phantom read (A读取若干行(设为集合X1)符合条件rule1(基于所有行),B修改集合X1外的行(未被上锁),改变了条件rule1。A的实际结果被改变,与之前的读取结果不一致)。

2)解决办法: 索引锁 index lock (限制了rule)

 

ps: 数据库引擎一般会有不同的 isolation level 的选择

read uncommitted  

read committed      no脏读

repeatable read      no不可重读

serializable             no幻读

选择合适的锁,保证并发性的情况下提高性能。

 

posted @ 2016-01-12 11:30  付小同  阅读(839)  评论(0编辑  收藏  举报