1. 程式人生 > >設定SQLServer的行版本控制隔離級別

設定SQLServer的行版本控制隔離級別

複製程式碼
--認清SQL_Server的基於行版本控制的兩種隔離級別
--快照隔離級別(snapshot)和已提交讀快照隔離級別(read committed snapshot)

--特點:在這兩種隔離級別下,讀取資料時不再請求共享鎖,而且永遠不會與修改程序的資料發生衝突,如果請求的行被鎖定(例如正在被更新),
--SQL_Server會從行版本儲存區返回最早的關於該行的記錄

--說明:首先這兩種隔離級別都是基於快照的實現模式,所以使用前必須修改資料庫選項"允許快照隔離"為ON,否則

--        以下兩種隔離級別將都被禁用:
        ALTER DATABASE DBNAME SET
ALLOW_SNAPSHOT_ISOLATION ON -- 修改這個選項時可能會需要將資料庫置為單使用者模式 ALTER DATABASE DBNAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE -- 修改完允許快照隔離後再將資料庫重置為多使用者模式 ALTER DATABASE DBNAME set MULTI_USER -- 一、快照隔離級別是一種全新的隔離級別,在開啟“允許快照隔離”選項後,不管是否使用快照隔離級別-- 在更新資料時,SQL SERVER總是會在tempdb庫中儲存更改前的最後的行資料鏈接列表,從這裡可以想到
-- 將會影響SQL SERVER在更新資料時的事務效能。當然,該隔離級別的主要作用是提高併發,所以讀取多,修改少的時候可大膽使用. SET TRANSACTION ISOLATION LEVEL SNAPSHOT -- 二、已提交讀快照隔離級別,其實就是SQL Server預設隔離級別Read Committed的衍生品,或者說是 -- 另一種版本的已提交讀,開啟此資料庫選項的命令是: ALTER DATABASE DBNAME SET read_committed_snapshot ON -- 在這裡大家要明白,它只是一個數據庫選項開關,是在 READ COMMITTED 隔離模式下時才會起作用,而且
-- 將改變整個資料庫的全域性行為。因為SQL SERVER預設就是在READ COMMITTED隔離模式下,所以在稍後的 -- 示例中我們不會用到SET TRANSACTION ISOLATION LEVEL READ COMMITTED語句,但是我們心裡要明白。 --適用情況:主要是讀取資料的環境,在這種環境下偶爾需要修改操作並且很少發生更新衝突。 --區別:我們會在稍後的演示中進行說明,那樣更容易理解一些。 --示例一:快照 --建立環境: IF DB_ID('DB_TEST') IS NOT NULL DROP DATABASE DB_TEST; GO CREATE DATABASE DB_TEST USE DB_TEST; GO IF OBJECT_ID('T_TEST','U') IS NOT NULL DROP TABLE T_TEST GO CREATE TABLE T_TEST(ID INT IDENTITY(1,1),COL VARCHAR(50)) GO INSERT INTO T_TEST SELECT 'AAAAAAAAA' UNION ALL SELECT 'BBBBBBBBBB' GO SELECT * FROM T_TEST /* ID COL 1 AAAAAAAAA 2 BBBBBBBBBB */ -- 在連線1中執行如下語句(確保ALLOW_SNAPSHOT_ISOLATION已置為ON) USE DB_TEST; GO ALTER DATABASE DB_TEST SET ALLOW_SNAPSHOT_ISOLATION ON; GO BEGIN TRAN SELECT COL FROM T_TEST WHERE ID=2; UPDATE T_TEST SET COL='CCCCCCC' WHERE ID=2; SELECT COL FROM T_TEST WHERE ID=2; -- 通過輸出的結果我們可以看到,在未完成的事務中ID=2的COL值從'B'變為'C',而且你應該注意到我這裡沒有使用快照隔離級別,還是用的SQL SERVER預設隔離級別,-- 但是因為我們打開了ALLOW_SNAPSHOT_ISOLATION選項,這個時候,我們的事務應該在更改ID=2的COL值之前就把之前的行狀態儲存到了tempdb中, -- 那麼我們怎麼才能證明這個猜測呢,動態檢視sys.dm_tran_version_store可以幫助我們,執行: SELECT * FROM sys.dm_tran_version_store -- 你一定可以看到在版本儲存區中已經有了一行資料了,接下來我們再開啟一個連線2,執行如下SQL: USE DB_TEST GO --SET TRANSACTION ISOLATION LEVEL SNAPSHOT; --這裡我們先註釋掉設定隔離級別為快照模式 BEGIN TRAN SELECT COL FROM T_TEST WHERE ID=2; -- 可以看到查詢一直在等待,是因為我們在連線1中一直保持著該行的排它鎖X。但是現在我們把該事務commit或rollback -- 掉,然後把快照隔離模式的註釋開啟,重新執行上面的語句,我們就可以看到 /* BBBBBBBBBB */ -- 我們可以想象到SQL SERVER在這種隔離級別下的查詢思路,它會先去原表查詢該行資料,待發現該行被鎖後,則去 -- tempdb資料庫儲存的行版本列表中取出最近的一次資料,這樣就避免了等待,但是前提是要求資料查詢不用那麼精確 -- 的情況下,當然,你是否在這裡忽略了一個問題,即:SQL SERVER僅會在修改該行資料前才會去儲存最新的行版本, -- 而在修改的事務結束後,SQL SERVER並不會去更新之前的快照到最新的行版本,但是即使這樣我們也不用擔心,因為 -- 這個時候原表的該行資料已經不是鎖定狀態,其他之後的查詢依然會得到最新的資料。唯一注意的一點,我們還是用 -- 程式碼說明:在連線1中用COMMIT TRAN 提交事務,然後繼續執行連線2中的查詢: SELECT COL FROM T_TEST WHERE ID=2; -- 我們發現數據還是之前的資料BBBBBBB,為什麼?因為事務隔離級別!在事務中的任何地方讀取該行資料時,它獲取的 -- 總是在事務開始時獲取的資料,這裡要牢記,因為他是稍後我們要說的已提交讀快照隔離級別的第一個不同點。 -- 接下來我們說說快照隔離級別的另一個特點:衝突檢測,程式碼說明,簡潔易懂: -- 在連線1中執行如下語句: USE DB_TEST; GO SET TRANSACTION ISOLATION LEVEL SNAPSHOT;--注意這裡我們要設定隔離級別為快照模式 BEGIN TRAN SELECT COL FROM T_TEST WHERE ID=2; -- 這裡我們可以得到一個數據,然後再開啟一個連線2,執行如下SQL: USE DB_TEST; GO UPDATE T_TEST SET COL='DDDDDDD' WHERE ID=2; -- 回到連線1,繼續執行SQL: UPDATE T_TEST SET COL='EEEEEEE' WHERE ID=2; -- 這時SQL SERVER 就會檢測到你在連線1中事務開始時讀取的資料已經與現在的資料發生了改變,所以就會報出更新 -- 衝突的錯誤: /* 訊息 3960,級別 16,狀態 4,第 1 行 快照隔離事務由於更新衝突而中止。您無法在資料庫'DB_Test'中使用快照隔離來直接或間接訪問表 'dbo.T_TEST', 以便更新、刪除或插入已由其他事務修改或刪除的行。請重試該事務或更改 update/delete 語句的隔離級別。 */ -- 這裡,其實就是快照隔離級別和已提交讀快照隔離級別的第二大區別了,READ COMMITTED SNAPSHOT不會檢測更新衝突 --示例二:已提交讀快照 -- 在連線1中執行如下語句: ALTER DATABASE DB_TEST SET READ_COMMITTED_SNAPSHOT ON;--首先我們開啟該資料庫選項 USE DB_TEST; GO; BEGIN TRAN UPDATE T_TEST SET COL='FFFFFFF' WHERE ID=2; SELECT COL FROM T_TEST WHERE ID=2; -- 在該事務裡,你將得到你剛剛更新過的值FFFFFFFF -- 在連線2中執行如下語句: USE DB_TEST; GO BEGIN TRAN SELECT COL FROM T_TEST WHERE ID=2; -- 這裡你將得到連線1中的事務在修改資料之前的值,而非FFFFFF,這是肯定的。 -- 這時我們提交連線1中的事務: COMMIT TRAN; -- 在連線2中再進行查詢時,我們驚奇的發現與在快照中不同的是,我們竟然在未完成的事務2中得到了連線1中的事務 -- 更改後的值!這也是為什麼不會進行更新衝突檢測的原因,不如我們測試一下: -- 將之前連線1中的事務提交或回滾,然後執行如下SQL: USE DB_TEST; GO SET TRANSACTION ISOLATION LEVEL READ COMMITTED;--這裡我們顯示指定隔離級別是因為剛才指定的快照隔離 -- 級別會在沒有關閉的會話中一直有效。 BEGIN TRAN SELECT COL FROM T_TEST WHERE ID=2; --之後,我們再把連線2中的事務提交或回滾掉,執行如下SQL: SET TRANSACTION ISOLATION LEVEL READ COMMITTED; UPDATE T_TEST SET COL='aaaaa' WHERE ID=2; SELECT COL FROM T_TEST WHERE ID=2; -- 好了,這個時候我們再在連線1中更新這條在事務1中讀取後但是在外部被更新過的資料: UPDATE T_TEST SET COL='測試已提交讀更新衝突檢測' WHERE ID=2; -- 我們發現更新可以正常進行,最後我們關閉所有連線,並更改資料庫選項: ALTER DATABASE DB_TEST SET ALLOW_SNAPSHOT_ISOLATION OFF; ALTER DATABASE DB_TEST SET READ_COMMITTED_SNAPSHOT OFF; --總結:快照隔離模式是樂觀併發模型,可以避免髒讀、丟失更新、不可重複讀、幻讀、而且有更新衝突檢測的特點。 --已提交快照讀隔離模式和已提交讀模式是相同的,都只能避免髒讀,都無更新衝突檢測,但是不同的是,已提交讀快照隔離級別是樂觀併發模型,並且讀取資料不會發生等待 --另附所有隔離級別的允許或防止的問題等。 ============================================================================================== 隔離級別 髒讀 丟失更新 不可重複讀 幻讀 併發模型 更新衝突檢測 ---------------------------------------------------------------------------------------------- 未提交讀 是 是 是 是 悲觀 否 ---------------------------------------------------------------------------------------------- 已提交讀   否 是 是 是 悲觀 否 ---------------------------------------------------------------------------------------------- 可重複讀 否 否 否 是 悲觀 否 ---------------------------------------------------------------------------------------------- 可序列讀 否 否 否 否 悲觀 否 ---------------------------------------------------------------------------------------------- 快照 否 否 否 否 樂觀 是 ---------------------------------------------------------------------------------------------- 已提交讀快照 否 是 是 是 樂觀 否 ==============================================================================================
複製程式碼

相關推薦

設定SQLServer版本控制隔離級別

--認清SQL_Server的基於行版本控制的兩種隔離級別 --快照隔離級別(snapshot)和已提交讀快照隔離級別(read committed snapshot) --特點:在這兩種隔離級別下,讀取資料時不再請求共享鎖,而且永遠不會與修改程序的資料發生衝突,如果請求的行被鎖定(例如正在被更新),

sqlserver 隔離級別 - 轉

添加 span scrip com gif key log rain 讀取數據 SQL-92標準中定義了四個隔離級別,這四個隔離級別在以前版本的SQL Server中即受到支持: READ UNCOMMITTED READ UNCOMMITTED是限制性最弱的隔離級別,

數據庫 之 事務控制隔離級別

可能 處理 eas 獨立 ble space 銷毀 實現 rac 1 概述事務是指一組原子性的SQL查詢、或者是一個或多個SQL語句組成的獨立工作單元;MyISAM不流行的原因很大是因為其不支持事務的處理功能。2 事務日誌事務日誌定義屬性,有些參數可以運行時修改,寫入在

事務的隔離級別的演示:演示串

演示串行化1.1.1 演示串行化l 開啟兩個窗口A,Bl 設置A窗口的隔離級別:serializableSET SESSION TRANSACTION ISOLATION LEVEL serializable;l 分別在兩個窗口中開啟事務:start transaction;l 在B窗口中插入一條記錄inse

DB2中幾個隔離級別select..for update with ** 的

最近專案中遇到了多執行緒高併發專案db2資料庫表死鎖的情況,蒐集了一些關於表死鎖的資料 Create table RRTest (pkID VARCHAR(20) NOT NULL ,unID1&nb

Hibernate設定事務的隔離級別

方式有兩種: 1)修改配置檔案hibernate.cfg.xml實現 <hibernate-configuration> <session-factory> ....

筆記——spring基本使用(控制反轉IOC、面向切面程式設計AOP、宣告式事務,事務隔離級別、事務傳播)

spring溫習筆記 Spring是一個開放原始碼的設計層面框架,他解決的是業務邏輯層和其他各層的鬆耦合問題,因此它將面向介面的程式設計思想貫穿整個系統應用。 Spring 的控制反轉IOC、面向切面程式設計AOP等特性不多說。 本文核心內容:搭建一個Spring Dem

SQLServer事務的隔離級別

轉自:http://www.cnblogs.com/qanholas/archive/2012/01/02/2310164.html 資料庫是要被廣大客戶所共享訪問的,那麼在資料庫操作過程中很可能出現以下幾種不確定情況。 更新丟失(Lost update)   兩

sqlserver 事務隔離級別

SQL Server通過在鎖資源上使用不同型別的鎖來隔離事務。為了開發安全的事務,定義事務內容以及應在何種情況下回滾至關重要,定義如何以及在多長時間內在事務中保持鎖定也同等重要。這由隔離級別決定。應用不同的隔離級別,SQL Server賦予開發者一種能力,讓他們為每一個單獨事

PPT控制元件Spire.Presentation 教程:在PPT中設定高度和列寬度

本文演示如何使用C#和VB.NET中的Spire.Presentation在PowerPoint文件中設定現有表的行高和列寬。 以下螢幕截圖顯示了設定行高和列寬之前的表。 詳細步驟: Step 1: 例項化Presentation物件並載入PowerPoint文

MySql事務(JDBC手動控制事務 事務的特性 事務的隔離級別

MySql事務 事務的概述: 事務指邏輯上的一組操作,組成這組操作的各個單元,要麼全部成功,要麼全部不成功。 事務案例: A–B轉賬,有以下兩條sql語句: update count set money=money+100 where name=’

JPA中幾種比較好的設定資料庫連線事務隔離級別的方法

在使用JPA時,有時候需要設定連線的事務隔離級別,以下幾種方法可供參考。 1). 直接在DataSource上設定DataSource source = (javax.sql.DataSource)

通過TransactionDefinition介面來學習spring事務的隔離級別和傳播特性(4.3.4版本

通過spring官方包中帶的原始碼來看spring的事務的5中隔離級別和7種傳播特性;     原始碼如下: /* * Copyright 2002-2015 the original author or authors. * * Licensed under th

資料庫事物隔離級別設定(針對多執行緒)

資料庫的髒讀、不可重複讀、幻讀都和事務的隔離性有關。所以先了解一下事務的4大特性。 事務的4大特性(ACID):原子性(Atomicity):事務是資料庫的邏輯工作單位,它對資料庫的修改要麼全部執行,要麼全部不執行,通俗點就是開啟了一個事物,那麼這個事物內的所有操作(增刪改s

mysql的事務隔離級別

too con jpg 級別 tran 開啟 數據行 修改 ges 原文地址:http://www.cnblogs.com/snsdzjlz320/p/5761387.html [Mysql]——通過例子理解事務的4種隔離級別 SQL標準定義了4種隔離級別,包括了一

事務與隔離級別筆記

講解 三種 span http ont nbsp 隔離 server bsp SQL Server 2008 R2 事務與隔離級別實例講解 筆記 1、事務是數據庫的工作單元,可視為一個原子操作,要麽成功,要麽什麽也不曾發生   事務操作的三種命令:     a、     事

基於GitLab與Git Extensions搭建版本控制工具

基本 cmd img html nat 需求 無法 spa hang 1.背景   大家知道GitHub是現在非常流行的代碼托管工具,但是如果有些項目不想開源的話,則需要付費,因此萌生了自己搭建一個Git的版本控制工具,供內網使用。GitLab則是個好的選擇,但是GitL

mysql ACID與四種隔離級別歸納總結

重新 style 出現 等待 mic 復讀 級別 for 保存 關於數據庫的ACID特性已經有很多的介紹,這裏再重新歸納總結一下: A(atomicity)原子性:   即事務要麽全部做完,要麽全部不做,不會出現只做一部分的情形,如A給B轉帳,不會出現A的錢少了,

事務隔離級別的理解

回滾 自己 避免 ron ref blank 提交 範圍 聯系 數據庫事務的隔離級別有4種,由低到高分別為Read uncommitted 、Read committed 、Repeatable read 、Serializable 。而且,在事務的並發操作中可能會出現臟讀

git 對 Microsoft Word 進行版本控制

dcl code 版本控制系統 documents custom ec2 adobe pen you   昨天中國高校發生了一件駭人聽聞的事情,聽說不少高校的校園網用戶連接校園網被勒索病毒給黑了,重要文件全部被加密,必須要支付贖金才能解密,具體新聞可以參見:http://w