写写并发控制:
只需要在写入(或更新)之前先获取行锁,如果获取不到,说明已经有其他线程拿了该锁,就需要不断重试等待或者自旋等待,直至其他线程释放该锁。拿到锁之后开始写入数据,写入完成之后释放行锁即可。这种行锁机制是实现写写并发控制最常用的手段,后面可以看到MySQL也是使用行锁来实现写写并发的。
批量写入多行的写写并发:
HBase支持批量写入(或批量更新),即一个线程同时更新同一个Region中的多行记录。那如何保证当前事务中的批量写入与其他事务中的批量写入的并发控制呢?思路还是一样的,使用行锁。但这里需要注意的是必须使用两阶段锁协议,即:
(1) 获取所有待写入(更新)行记录的行锁
(2) 开始执行写入(更新)操作
(3) 写入完成之后再统一释放所有行记录的行锁
不能更新一行锁定(释放)一行,多个事务之间容易形成死锁。两阶段锁协议就是为了避免死锁,MySQL事务写写并发控制同样使用两阶段锁协议。
Rowkey info:company info:role
greg cloudera engineer
Rowkey info:company info:role
greg restaurant waiter
两个并发写入请求同时进来,分别对一行数据进行写入。若没有并发控制,会出现交叉情况。
Rowkey info:company info:role
greg restaurant engineer
读写并发控制:
事务A完成。
Rowkey info:company info:role
greg cloudera engineer
开始执行事务B
Rowkey info:company
greg restaurant
此时来了读请求,info:role还未更新完成。
info:role
waiter
读取到的数据为:
Rowkey info:company info:role
greg restaurant engineer
出现数据不一致的情况。
多版本并发控制(MVCC机制-Mutil Version Concurrent Control):
两个写事务分别分配了序列号1和序列号2,读请求进来的时候事务1已经完成,事务2还未完成,因此分配事务1对应的序列号1给读请求。此时序列号1对本次读可见,序列号2对本次读不可见。
+---+---+---+---+---+---+---+---+---+----+----+----+----+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
+---+---+---+---+---+---+---+---+---+----+----+----+----+
所有事务都会生成一个region级别的自增序列。
1、如果事务1和事务2和事务3是操作的同一行,事务1完成,事务2未完成,事务3完成。此时读请求过来读取该行,只能读取到事务1.当事务2完成后才能读取到事务3
2、如果事务1~事务12操作的不同行,事务1~事务11都未完成,事务12完成,此时读请求过来读取事务12的数据,仍旧会等待事务1~事务11完成后才能读取事务12的内容,
所以此时读取到的是事务12对应行的之前的事务内容。因为目前还未做到对未完成的事务与当前读请求的内容比较的功能,而且一个事务中可能包含多行。若要与当前请求比较,
会比较耗性能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。