做為一個後端工程師,除了要理解程式碼的運作以及副作用之外,對於資料庫的溝通也是重要一課,也許剛開始時沒那麼關鍵,但隨著系統的規模逐漸擴大,你對於系統的了解本身就變得相當重要了。
提到資料庫的存取,我們就不免地提到幾乎是家喻戶曉的ACID定律了。ACID是關聯式資料庫的基本特性,他們規範了一個交易,也就是與資料庫溝通的一個單位,必須具備甚麼特性。他們分別由:
共四樣組成,後續被開發出來的NOSQL等等,雖然沒有完全實現所有的特性,但也有不少做到了部分的實現,其重要度可見一斑。
原子性代表一個操作必須是全部成功、要不然就是全部失敗。舉例來說,你在麥當勞點了套餐並得到了加一元多一件的大薯,你無法在不買套餐,只用一元獲得大薯,這就是原子性。
一致性代表一個交易的前後都必須要符合完整性的規範,寫入的資料必須完全符合所有規範,套用同樣的約束、Trigger等等。
隔離性是一種資料庫處理多個併發交易對資料進行讀寫的能力,隔離性有分為四種級別來根據各種不同需求的商業場景進行操作。
持久性代表了交易對資料庫的寫入是永久的,不會因為系統的異常導致資料消失。
這些規範看起來很合理,但未必適合每種商業場景,實際上還是要多多考慮實際上的商業場景在做出決定。就好比高可用性與系統效能永遠都是一個無法兼得的選項一樣。端看你要如何取捨。
在這四項RDBMS的特性中,隔離性是最為複雜的一種,關於隔離性的設定往往沒有最佳解答,只有想出最合適的選項,並接受他的tradeoff(代價)。
在開始提隔離層級前,我們先來回憶一下之前提到的Hibernate建立一段會話的生命流程。
// 開啟Session,相當於開啟JDBC的Connection
Session session = HibernateUtil.getSessionFactory().openSession();
// Transaction表示一組會話操作
Transaction tx= session.beginTransaction();
// 將物件映射至資料庫表格中儲存
session.save(user);
tx.commit();
session.close();
根據上面的說明,可以總結出一個會話是這樣的:
簡單帶過會話後,我們回到原先的話題,來開始提四種隔離層級吧,由最寬鬆到最嚴謹分別是:
另外,如果提到效能的話,排序就剛好相反,最上面的效率最快,最下面的效率最差,開發者必須要根據實際需求,設定合理的隔離層級。
納今天我們就講到這裡啦,明天見 掰掰。