1. 程式人生 > >撩課-Java每天5道面試題第16天

撩課-Java每天5道面試題第16天

111.什麼是樂觀鎖(Optimistic Locking)?

悲觀鎖,正如其名,
它指的是對資料被外界
包括本系統當前的其他事務,
以及來自外部系統的事務處理
修改持保守態度,
因此,在整個資料處理過程中,
將資料處於鎖定狀態。
 悲觀鎖的實現,
往往依靠資料庫提供的鎖機制 
也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,
否則,即使在本系統中實現了加鎖機制,
也無法保證外部系統不會修改資料

樂觀鎖( Optimistic Locking ) 
相對悲觀鎖而言,
樂觀鎖假設認為資料
一般情況下不會造成衝突,
所以在資料進行提交更新的時候,
才會正式對資料的衝突與否進行檢測,
如果發現衝突了,
則讓返回使用者錯誤的資訊,
讓使用者決定如何去做

 

112.描述下Hibernate當中事務?

一、事務的併發問題 
在實際應用中,
資料庫是要被I多個使用者共同訪問的,
在多個事務同時使用相同的資料時,
可能會發生併發的問題,
具體為:

髒讀:
一個事務讀取到
另一個事務未提交的資料。

不可重複讀:
一個事務對同一行資料
重複讀取兩次,
但是得到了不同的結果。

虛讀:
一個事務連續兩次在資料庫進行同樣條件的查詢,
但是第二次查詢結果包含了
第一次查詢中未出現的資料。
(注意與不可重複讀的區別)

更新丟失:
兩個事物同時更新一行資料,
後提交(或撤銷)的事務將前面事務
提交的資料都覆蓋了。 
第一類丟失更新:
是由於後面事務撤銷將前面事務
修改的資料覆蓋了 
第二類丟失更新:
是由於後面事務更新將前面事務
修改的資料覆蓋了


1、讀未提交(1級,可防止更新丟失): 當一個事務進行寫(更新)資料, 則另外一個事務不允許同時進行寫(更新)資料, 但允許其他事務進行讀資料, 即使是未提交的 (但這個不能防止髒讀) 更新丟失是因為一個事務開始進行寫事務, 另一個事務也可以進行寫事務導致的。 2、讀已提交(2級,可防止更新丟失、髒讀): 讀取資料的事務允許其他事務繼續讀取該資料, 但是未提交的寫事務將會禁止其他事務訪問改行。 髒讀是由於讀到未提及的資料 3、可重複讀(4級,可防止不可重複讀、髒讀): 讀取資料的事務禁止寫事務, 寫事務將禁止其他任何事務。 不可重複讀是一個事務 對一行資料重複讀取兩次, 但是得到不同的結果; 髒讀是讀到未提交的資料
4、序列化(8級,防止一切併發問題): 提供嚴格的事務隔離。 事務只能一個接著一個執行, 不能併發執行 簡單總結: 事務併發問題: (1)髒讀 (2)不可重複讀 (3)虛讀 (4)更新丟失 事務隔離級別: (1)讀未提交 (2)讀已提交 (3)可重複讀 (4)序列化 在hibernate.cfg.xml的標籤配置: 使用本地事務還是全域性事務,引數是: hibernate.current_session_context_class 值:thread(本地事務)、jta(全域性事務) 設定事務隔離級別,引數是: hibernate.connection.isolation 當多個事務同時訪問資料庫中的相同資料時, 如果沒有采取必要的隔離措施, 那麼可以採用悲觀鎖或者是樂觀鎖對其進行控制。 悲觀鎖: 悲觀地認為總是會有其他事務回來操作同一資料 因此在這個資料處理過程中, 將會把資料處於鎖定狀態。 比如讀取資料時: User user = (User)session.get(User.class, "111111", LockMode.UPGRADE) 樂觀鎖: 認為事務同時操作同一個資料的情況很少發生, 所以樂觀鎖不做資料庫層次的鎖定, 而是基於資料版本標識 實現應用程式級別上的鎖定機制。 原理:資料版本標識, 是指通過為資料表增加一個“version”欄位, 實現在讀取資料時, 將版本號一同獨處, 之後更新次資料時, 將此版本號加一; 在提交資料時, 將現有的版本號 與資料表對應的記錄的版本號進行對比, 如果提交資料的版本號大於資料表中的版本號, 則允許更新資料, 否則禁止更新資料。

 

113.Hibernate 中的快取分為幾層。

hibernate的快取包括 
Session的快取和SessionFactory的快取,
其中SessionFactory的快取又可以分為兩類:
內建快取和外接快取。
Session的快取是內建的,
不能被解除安裝,
也被稱為Hibernate的第一級快取。
SessionFactory的內建快取
和Session的快取在實現方式上比較相似,
前者是SessionFactory物件的一些集合屬性包含的資料,
後者是指Session的一些集合屬性包含的資料。
SessionFactory的內建快取中存放了
對映元資料和預定義SQL語句,
對映元資料是對映檔案中資料的拷貝,
而預定義SQL語句是
在Hibernate初始化階段根據
對映元資料推匯出來,
SessionFactory的內建快取是隻讀的,
應用程式不能修改快取中的對映元資料
和預定義SQL語句,
因此SessionFactory不需要進行內建快取與對映檔案的同步。
SessionFactory的外接快取是一個可配置的外掛。
在預設情況下,SessionFactory不會啟用這個外掛。
外接快取的資料是資料庫資料的拷貝,
外接快取的介質可以是記憶體或者硬碟。
SessionFactory的外接快取
也被稱為Hibernate的第二級快取

  

114.Entity Beans 的狀態有哪些

瞬時(transient):
資料庫中沒有資料與之對應,
超過作用域會被JVM垃圾回收器回收,
一般是new出來且與session沒有關聯的物件。

持久(persistent):
資料庫中有資料與之對應,
當前與session有關聯,
並且相關聯的session沒有關閉,
 事務沒有提交;
持久物件狀態發生改變,
在事務提交時會影響到資料庫(hibernate能檢測到)。

脫管(detached):
資料庫中有資料與之對應,
但當前沒有session與之關聯;
託管物件狀態發生改變,
hibernate不能檢測到。

 

115.談談Hibernate中inverse的作用

Hibernate中的inverse
在表關係對映中經常應用
 inverse的值有兩種,“true”和“false”。

inverse="false"是預設的值 
inverse的作用:
在hibernate中是通過inverse的設定
來決定是有誰來維護表和表之間的關係的。

 我們說inverse設立不當會導致效能低下,
其實是說inverse設立不當,
會產生多餘重複的SQL語句
甚至致使JDBC exception的throw。

這是我們在建立實體類關係時
必須需要關注的地方。

一般來說,inverse=true是推薦使用,
雙向關聯中雙方都設定 inverse=false的話,
必會導致雙方都重複更新同一個關係。

但是如果雙方都設立inverse=true的話,
雙方都不維護關係的更新,
這也是 不行的,
好在一對多中的一端:
many-to-one預設是inverse=false,
避免了這種錯誤的產生。

但是多對多就沒有這個預設設定了,
所以很 多人經常在多對多的兩端都使用inverse=true,
結果導致連線表的資料根本沒有記錄,
就是因為他們雙分都沒有責任維護關係。
所以說,雙向關聯中最 好的設定
是一端為inverse=true,
一端為inverse=false。

一般inverse=false會放在多的一端,
那麼有人提問了, many-to-many兩邊都是多的,
inverse到底放在哪兒?
其實hibernate建立多對多關係
也是將他們分離成兩個一對多關係,
中間連線一個連線表。

所以通用存在一對多的關係,
也可以這樣說:
一對多是多對多的基本組成部分。