What is Transaction
先摘錄一段Wiki關於Transaction(事務)的釋義:
A transaction comprises a unit of work performed within a database management system (or similar system) against a database, and treated in a coherent and reliable way independent of other transactions. Transactions in
a database environment have two main purposes:
1. To provide reliable units of work that allow correct recovery from failures and keep a database consistent even in cases of system failure, when execution stops (completely or partially) and many operations upon a database
remain uncompleted, with unclear status.
2. To provide isolation between programs accessing a database concurrently. If this isolation is not provided, the program's outcome are possibly erroneous.
A database transaction, by definition, must be atomic, consistent, isolated and durable. Database practitioners often refer to these properties of database transactions using the acronym ACID.
Transactions provide an "all-or-nothing" proposition, stating that each work-unit performed in a database must either complete in its entirety or have no effect whatsoever. Further, the system must isolate each transaction
from other transactions, results must conform to existing constraints in the database, and transactions that complete successfully must get written to durable storage.
其中,all-or-nothing很明確的表達了事務的本質:“要麼全成功,要麼什麼都沒發生過”。可以把它看作一個原子操作。
HBase Transaction
HBase的支持的事務很有限,0.94版本的新特性中有兩條:
[HBASE-3584] - Allow atomic put/delete in one call.
[HBASE-5229] - Provide basic building blocks for "multi-row" local transactions.
第一條,我引用NoSQLFan的解讀:
“0.94版本具備更完整的事務支持: 之前Hbase提供行級的事務,不過每次事務只能執行一個寫操作,比如連續地執行一系列Put,Delete操作,那麼這些操作是單獨一個個的事務,其整體並不是原子性執行的。而在0.94版本中,可以實現Put、Delete在同一個事務中一起原子性執行。”
具體怎麼用呢?有下面這一段Sample:
//Add API for atomic row mutations to HBase (currently Put and Delete).
Client API would look like this:
Delete d = new Delete(ROW);
Put p = new Put(ROW);
//...
AtomicRowMutation arm = new AtomicRowMutation(ROW);
arm.add(p);
arm.add(d);
myHtable.atomicMutation(arm);
可以看到,這裏的事務僅僅是針對某一行的一系列Put/Delete操作。不同行、不同表間一系列操作是無法放在一個事務中的。
第二條,我的個人理解,這次是多行一併的事務了!不過貌似是“同一Region中的多行”。因爲文中一句“ Global (cross region) transactions are not discussed here.”
因此對一張多Region表來說,還是無法保證每次修改都能封裝爲一個事務。
What We Need
結合我之前的博文《HBase多條件查詢》,我們通常需要爲了查詢而建立多個索引表。
比如我Save一條player數據,主表(信息完整表)的rowKey是以ID構成,順序排列。
我如果需要按player的積分(Scores)排個TOP 10,我可能還需要用(Max - player.getScores) + ID建一張索引表。同理可能還有多個……
每當插入一條player記錄,我需要同時對這兩個rowKey進行put操作。
這,就已經超出了HBase支持的事務範疇(同一行的一系列操作事務)。
此處無事務會怎樣?比如我新增一個player,首先執行IDTbl.put,再執行ScoresTbl.put。
在執行第二步ScoresTbl.put時與HBase Cluster的網絡中斷了,此時ScoresTbl.put超時失敗,但IDTbl.put已經成功完成了。
如果僅僅在業務層做了RollBack,此時應該會執行IDTbl.delete,但是網絡中斷,delete操作一樣會失敗。
網絡恢復了!
最終,我們新增的這位Player登錄進來(因爲IDTbl.put中有他的記錄,所以可以成功登錄)。
在點擊“查看我的排名”按鈕時會觸發ScoresTbl.get操作,但ScoresTbl中沒有他的記錄,對後續操作會有不可預知的影響。
如果,我們有10幾張索引表……
因此,事務是必須的!
What Can We Do
爲了解決這種不同記錄、不同表間的事務問題,我看到兩個項目。
1、yahoo/omid
2、Indexed Transactional HBase
blog:http://blog.csdn.net/pirateleo
email:[email protected]
轉載請註明出處,謝謝。
由於文中在發佈後難免會有勘誤或補充,推薦到本博客中閱讀本文。