莫要太信任數(shù)據(jù)庫,你會失望的
數(shù)據(jù)庫啊,數(shù)據(jù)庫!雖然現(xiàn)在應(yīng)用架構(gòu)強調(diào)業(yè)務(wù)邏輯不依賴數(shù)據(jù)庫,僅把數(shù)據(jù)庫作為信息存儲的手段。但是國內(nèi)的情況似乎還是挺以數(shù)據(jù)庫為中心的。數(shù)據(jù)庫雖然存在了多年,也算成熟了,但是很多書上其實對如何有效使用數(shù)據(jù)庫的強調(diào)很不夠。
尤其是對java而言,JDBC是java訪問數(shù)據(jù)庫的標準,也就是獨立于數(shù)據(jù)庫的。雖然如此,數(shù)據(jù)庫廠商大概不會為了jdbc去改自己的數(shù)據(jù)庫,要知道,數(shù)據(jù)庫肯定是要提供多種接口方式的,比如C。數(shù)據(jù)庫一改,這些接口很可能都要改,這就不好了,還可能因為接口做不到向下兼容得罪現(xiàn)有用戶。于是,成本比較低的做法,就變成了在jdbc層做手腳,也就是通常所說的“忽悠”。
有些數(shù)據(jù)庫其實不支持預(yù)編譯sql的,但是仍然支持PrepareStatement,這里就會引起使用者的困惑,不清楚它內(nèi)部到底是怎么實現(xiàn)的。 還有些數(shù)據(jù)庫其實不支持jdbc所提供的那些事務(wù)隔離級別,或者跟jdbc規(guī)定的那些沒有嚴格對應(yīng)關(guān)系。這就更令人惱火了,經(jīng)常有人抱怨設(shè)置隔離級別沒有效果,大概就是這個原因所致。
數(shù)據(jù)庫還有一個很少被提及的問題,那就是并發(fā)問題中的第二類丟失更新。比如:兩個客戶端A、B對同一條訂單數(shù)據(jù)進行操作。事件序列如下:
A:打開訂單
B:打開訂單
A:保存修改
B:保存修改
aha!A的修改就很可能丟失了。不要抱怨數(shù)據(jù)庫怎么連這個都解決不了,其實并不是解決不了,而是沒有什么通用的方案,倒不如把它交給開發(fā)人員自行選擇方案的好。開發(fā)人員可以選擇樂觀鎖和悲觀鎖,一切都要根據(jù)業(yè)務(wù)情況來。
問題是,資料上邊很少提及會有這樣的情況發(fā)生,開發(fā)人員也就不曾處理過這個問題。根據(jù)我的理解,我覺得存在update操作的表都要進行這個處理,否則數(shù)據(jù)的正確性就無從保證。