### [PostgreSQL學習手冊(事物隔離)](http://www.cnblogs.com/stephen-liu74/archive/2012/05/11/2300863.html)
Posted on?2012-05-11 09:09?[Stephen_Liu](http://www.cnblogs.com/stephen-liu74/)?閱讀(1351) 評論(0)?[編輯](http://www.cnblogs.com/stephen-liu74/admin/EditPosts.aspx?postid=2300863)?[收藏](http://www.cnblogs.com/stephen-liu74/archive/2012/05/11/2300863.html#)?
??? 在SQL的標準中事物隔離級別分為以下四種:
?? ?1. 讀未提交(Read uncommitted)
?? ?2. 讀已提交(Read committed)
?? ?3. 可重復讀(Repeatable read)
?? ?4. 可串行化(Serializable)
?? ?然而PostgreSQL在9.1之前的版本中只是實現了其中兩種,即讀已提交和可串行化,如果在實際應用中選擇了另外兩種,那么PostgreSQL將會自動向更嚴格的隔離級別調整。在PostgreSQL v9.1的版本中提供了三種實現方式,即在原有的基礎上增加了可重復讀。在這篇博客中我們將只是針對2)和4)進行說明和比較,因為在9.1中,3)和4)的差別也是非常小的。
| ? | **讀已提交** | **可串行化** |
|-----|-----|-----|
| PostgreSQL缺省隔離級別 | 是 | 否 |
| 其它事物未提交數據是否可見 | 不可見 | 不可見 |
| 執行效率 | 高 | 低 |
| 適用場景 | 簡單SQL邏輯,如果SQL語句中含有嵌套查詢,那么在多次SQL查詢中將極有可能獲得不同版本的數據。 | 復雜SQL邏輯,特別是帶有嵌套的查詢比較適用。 |
| SELECT查詢一致性時間點 | 從該SELECT查詢開始執行時,在此查詢執行期間,任何其它并發事物針對該查詢結果集的數據操作都將不會被本次查詢讀到,即本次查詢獲取的數據版本是與查詢開始執行時的數據版本相一致。 | 從該SELECT查詢所在事物開始時,在此查詢執行期間,任何其它并發事物針對該查詢結果集的數據操作都將不會被本次查詢讀到,即本次查詢獲取的數據版本是與查詢所在事物開始時的數據版本相一致。 |
| 同事物內的數據操作是否可見 | 比如在同一個事物內存在update和select操作,即使當前事物尚未提交,update所作的修改,在當前事物后面的select中依然可見。 | 和讀已提交相同。 |
| 同事物內多次相同的select所見的數據是否相同 | 不同,由于該級別select的一致性時間點是該查詢開始執行時,而多次查詢的時間點將肯定不相同,如果在第一次查詢開始到第二次查詢開始之間,其它的并發事物修改并提交或當前事物僅修改了查詢將要獲取的數據,那么這些數據操作的結果將會在第二個查詢中有所體現。 | 需要分兩步來說,對于同一事物內的修改如果發生在兩次查詢語句之間,那么第二個查詢將會看到這些修改的結果。然而對于其它并發事物的修改,將不會造成任何影響,即兩次select的結果是相同的。原因顯而易見,該隔離級別的select一致性時間點是與事物開始時相一致的。 |
| 相同行數據的修改 | 如果此時兩個并發事物在修改同一行數據,先修改的事物將會給該行加行級鎖,另外一個事物將進入等待狀態,直到第一個事物操作該行結束。那么倘若第一個針對該行的修改操作最終被其事物回滾,第二個修改操作在結束等待后,將直接修改該數據。然而如果第一個操作是被正常提交的話,那么就需要進一步判斷該操作的類型,如果是刪除(delete)該行,第二個修改操作將直接被忽略。如果是update該行的記錄,第二個修改操作則需要重新評估該行是否依然符合之前定義的修改條件。 | 和讀已提交隔離級別的機制基本相同,只是在第一個修改操作提交后,第二個操作將不再區分之前的修改是delete還是update,而是直接并返回下面信息:Error: Can't serialize access due to concurrent update. 這是因為一個可串行化的事務在可串行化事務開始之后不能更改或者鎖住被其他事務更改過的行。因此,當應用收到這樣的錯誤信息時,它應該退出當前的事務然后從頭開始重新進行整個事務。在應用程序中,也應該有必要的代碼來專門處理該類錯誤。 |
??? 最后需要說明的是,在絕大多數的情況下,讀已提交級別均可適用,而且該級別的并發效率更高。只有在比較特殊的情況下,才手工將當前的事物隔離級別調整為可串行化或可重復讀。
分類:?[PostgreSQL](http://www.cnblogs.com/stephen-liu74/category/343171.html)
- 數據表
- 模式Schema
- 表的繼承和分區
- 常用數據類型
- 函數和操作符-一
- 函數和操作符-二
- 函數和操作符-三
- 索引
- 事物隔離
- 性能提升技巧
- 服務器配置
- 角色和權限
- 數據庫管理
- 數據庫維護
- 系統表
- 系統視圖
- SQL語言函數
- PL-pgSQL過程語言
- PostgreSQL 序列(SEQUENCE)
- PostgreSQL的時間-日期函數使用
- PostgreSQL 查看數據庫,索引,表,表空間大小
- 用以查詢某表的詳細 包含表字段的注釋信息
- PostgreSQL 系統表查看系統信息
- postgre存儲過程簡單實用方法
- PostgreSQL實用日常維護SQL
- PostgreSQL的時間函數使用整理
- 命令
- pg_ctl控制服務器
- initdb 初始化數據庫簇
- createdb創建數據庫
- dropdb 刪除數據庫
- createuser創建用戶
- dropuser 刪除用戶
- psql交互式工具
- psql命令手冊
- pg_dump 數據庫轉儲
- pg_restore恢復數據庫
- vacuumdb 清理優化數據庫
- reindexdb 數據庫重創索引
- createlang 安裝過程語言
- droplang 刪除過程語言
- pg_upgrade 升級數據庫簇
- 調試存儲過程
- 客戶端命令-一
- 客戶端命令-二
- 使用技巧
- PostgreSQL刪除重復數據
- postgresql 小技巧
- PostgreSQL的10進制與16進制互轉
- PostgreSQL的漢字轉拼音
- Postgres重復數據的更新一例
- PostgreSQL使用with一例
- PostgreSQL在函數內返回returning
- PostgreSQL中的group_concat使用
- PostgreSQL數據庫切割和組合字段函數
- postgresql重復數據的刪除
- PostgreSQL的遞歸查詢(with recursive)
- PostgreSQL函數如何返回數據集
- PostgreSQL分區表(Table Partitioning)應用 - David_Tang - 博客園
- PostgreSQL: function 返回結果集多列和單列的例子
- 利用pgAgent創建定時任務
- 淺談 PostgreSQL 類型轉換類似Oracle
- postgresql在windows(包括win7)下的安裝配置
- PostgreSQL簡介、安裝、用戶管理、啟動關閉、創建刪除數據庫 (2010-11-08 12-52-51)轉載▼標簽: 雜談分類: PostgreSQL
- PostgreSQL的generate_series函數應用
- PostgreSQL 8.3.1 全文檢索(Full Text Search)
- postgresql record 使用
- 備份恢復
- PostgreSQL基于時間點恢復(PITR)
- Postgresql基于時間點恢復PITR案例(二)
- Postgres邏輯備份腳本
- Postgres invalid command \N數據恢復處理