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