上次在學習項目的過程當中發現了一個這樣的配置,方法事務上@Transactional(value = "transactionManager",readOnly = true)
增長了一個readOnly = true
的配置,很好奇這有什麼用?原理是什麼?下面我將一一說說它是什麼以及在mysql、oracle中的區別。java
事務分爲只讀事務和讀寫事務,咱們第一反應會想到的含義是隻讀事務不容許你在一個事務中執行諸如update
、delete
、insert
的操做,你只能執行select
操做,可是,其實不是,只讀事務並非必須的,你一樣能夠在只讀事務中執行修改操做,只不過顯示聲明事務爲只讀模式,會讓相應的數據庫對你的事務進行一些優化操做而已。mysql
要演示只讀事務對 mysql、oracle 的支持,首先要作的就是把例子給搭建起來,下面我將描述相關測試用例:git
Spring 聲明式事務分爲兩種,一種是基於<tx>、<aop:config>
標籤的事務聲明,另一種是基於@Transacional
的註解聲明。咱們採用第二種方式聲明。github
很顯然,既然你要鏈接到 mysql、oracle 數據庫,那麼你就須要相應的數據庫驅動程序;因爲採用 Spring 進行事務管理,那麼相應的Spring 包必不可少;固然你還須要一個數據源,告訴相應的驅動程序你的數據從哪裏來;最後,我就不貼出代碼了,代碼太多,直接在github上看便可。sql
代碼github地址數據庫
mysql 提供對只讀事務的支持,事務的默認隔離級別爲「可重複讀」。session
編號 | 是否加事務 | 是否執行更新操做 | 事務是否只讀 | 執行結果 |
---|---|---|---|---|
1 | 否 | 否 | 屢次執行查詢,結果隨數據庫改變而改變 | |
2 | 否 | 是 | 屢次執行查詢,結果隨數據庫改變而改變 | |
3 | 是 | 否 | 否 | 屢次執行查詢,結果不隨數據庫改變而改變,讀視圖一致 |
4 | 是 | 是 | 否 | 屢次執行查詢,結果不隨數據庫改變而改變,讀視圖一致 |
5 | 是 | 否 | 是 | 屢次執行查詢,結果不隨數據庫改變而改變,讀視圖一致 |
6 | 是 | 是 | 是 | 執行更會報錯,提示 readOnly |
oracle 提供對只讀事務的支持,事務的默認隔離級別爲「read committed」。oracle
編號 | 是否加事務 | 是否執行更新操做 | 事務是否只讀 | 執行結果 |
---|---|---|---|---|
1 | 否 | 否 | 屢次執行查詢,結果隨數據庫改變而改變 | |
2 | 否 | 是 | 屢次執行查詢,結果隨數據庫改變而改變 | |
3 | 是 | 否 | 否 | 屢次執行查詢,結果隨數據庫改變而改變 |
4 | 是 | 是 | 否 | 屢次執行查詢,結果隨數據庫改變而改變 |
5 | 是 | 否 | 是 | 屢次執行查詢,結果隨數據庫改變而改變 |
6 | 是 | 是 | 是 | 結果隨數據庫改變而改變 |
有此可見,Spring 設置的readOnly事務屬性對oracle來講是無效的。學習
底層實現原理是基於JDBC的相關屬性設置,如:測試
(1)在JDBC中,指定只讀事務的辦法爲: connection.setReadOnly(true)
;
(2)在Hibernate中,指定只讀事務的辦法爲: session.setFlushMode(FlushMode.NEVER)
;
https://blog.csdn.net/msy_xingfu1314/article/details/50562991 當咱們查看 oracle 驅動官方文檔時會發現有,其實 Oracle 數據庫自己也是支持只讀事務的,也就是隻讀模式,可是文檔很明確的說明了只讀模式只能經過oracle數據庫自己進行設置:
Read-only connections are supported by the Oracle server, but not by the Oracle JDBC drivers.
For transactions, the Oracle server supports only the TRANSACTION_READ_COMMITTED and TRANSACTION_SERIALIZABLE transaction isolation levels. The default is TRANSACTION_READ_COMMITTED. Use the following methods of the oracle.jdbc.OracleConnection interface to get and set the level:
getTransactionIsolation: Gets this connection's current transaction isolation level.
setTransactionIsolation: Changes the transaction isolation level, using one of the TRANSACTION_* values.
對於使用jdbc驅動來講,你只能設置TRANSACTION_READ_COMMITTED
和 TRANSACTION_SERIALIZABLE
兩種隔離級別,若是你想要只讀事務,只能經過執行SET TRANSACTION READ ONLY
完成。小編找了兩篇更加全面的文章給你們參考
驗證相關的數據庫驅動能夠在這裏下載