學(xué)習(xí)spring常常聽說只讀事務(wù),到底什么是只讀事務(wù)?
“只讀事務(wù)”的提法太過籠統(tǒng).只讀事務(wù)可以分為兩個(gè)方面:JDBC和數(shù)據(jù)庫。 JDBC的Connection對(duì)象有一個(gè)方法setReadOnly。JDK的API描述如下: Java代碼
翻譯過來的意思“把此連接設(shè)置為只讀模式,作為的數(shù)據(jù)庫優(yōu)化的暗示”.這里面有事務(wù)隔離嗎?沒有。甚至SUN的描述都很模糊,只是向數(shù)據(jù)庫驅(qū)動(dòng)做一個(gè)啟動(dòng)數(shù)據(jù)庫優(yōu)化的暗示,不代表一定有效。所以不應(yīng)該把readOnly作為打開只讀事務(wù)的判斷。 robbin 在只讀查詢是否需要啟動(dòng)事務(wù)管理,兼論只讀事務(wù)的說法并不十分正確: robbin 寫道 在JDBC中,指定只讀事務(wù)的辦法為: connection.setReadOnly(true); 在Hibernate中,指定只讀事務(wù)的辦法為: session.setFlushMode(FlushMode.NEVER); 此時(shí),Hibernate也會(huì)為只讀事務(wù)提供Session方面的一些優(yōu)化手段 在Spring的Hibernate封裝中,指定只讀事務(wù)的辦法為: bean配置文件中,prop屬性增加“readOnly” 查看oracle的文檔對(duì)jdbc驅(qū)動(dòng)的描述: Java代碼
Oracle服務(wù)器支持Read-only ,這個(gè)又是什么意思呢? 為了搞清楚這個(gè)所謂的“只讀事務(wù)”必須先明確一個(gè)概念--“事務(wù)隔離級(jí)別(transaction isolation degree)”,ANSI標(biāo)準(zhǔn)定義了4個(gè)隔離級(jí)別標(biāo)準(zhǔn):
主流數(shù)據(jù)庫的一般的默認(rèn)是READ COMMITTED級(jí)別。 MYSQL和MS SQLServer遵守了這個(gè)定義而oracle沒有。oracle只有三種事務(wù)隔離等級(jí):
前兩個(gè)Read committed,Serializable 和ANSI的定義是一致的,來看看最關(guān)鍵的第三個(gè)Read-only 。Read-only事務(wù)只會(huì)看到在這個(gè)事務(wù)開啟時(shí)間點(diǎn)其他事務(wù)提交過的數(shù)據(jù),并且不允許執(zhí)行INSERT, UPDATE,DELETE語句,換句話說,在設(shè)置set transaction read only后,當(dāng)前會(huì)話所見的數(shù)據(jù)圖像,將不再受到其他會(huì)話事務(wù)的影響。 所以oracle支持的只讀事務(wù)不是為了優(yōu)化性能,而是為了讓這個(gè)事務(wù)中所有的查詢操作看到的數(shù)據(jù)是一個(gè)時(shí)間點(diǎn)(開啟事務(wù))上的一致數(shù)據(jù)。MYSQL,SQL_SERVER根本沒有只讀事務(wù)的概念,但是有REPEATABLE READ,具體看之間的差別。 有了這個(gè)基礎(chǔ)后,再看Connection對(duì)象也定義了五個(gè)變量和ANSI標(biāo)準(zhǔn)對(duì)應(yīng): Java代碼
而Spring也不過是在這上面做封裝。TransactionDefinition接口中定義了五個(gè)不同的事務(wù)隔離級(jí)別: Java代碼
既然沒有只讀事務(wù)的概念,那么提交一個(gè)查詢是否需要開啟一個(gè)事務(wù)呢? 不同的數(shù)據(jù)庫可能有不同實(shí)現(xiàn),oracle驅(qū)動(dòng)的文檔介紹: 如果關(guān)閉Disabling Auto-Commit Mode可以提高一定的性能。 但是MYSQL好像相反,參見:http://www./topic/1603?page=1 |
|