MSSQL事务开发指南
了解事務(wù)
?事務(wù)是作為單個(gè)邏輯工作單元執(zhí)行的一系列操作。可以是一條SQL語(yǔ)句也可以是多條SQL語(yǔ)句。
?事務(wù)具有四個(gè)特性
??原子性:不可分隔、成則具成、敗則具敗。
??一致性:事務(wù)在完成時(shí),必須使所有的數(shù)據(jù)都保持一致?tīng)顟B(tài)
??隔離性:獨(dú)立的執(zhí)行互不干擾。由并發(fā)事務(wù)所作的修改必須與任何其他并發(fā)事務(wù)所作的修改隔離。
??持久性:務(wù)完成之后,它對(duì)于系統(tǒng)的影響是永久性的。該修改即使出現(xiàn)系統(tǒng)故障也將一直保持。
?應(yīng)用程序主要通過(guò)指定事務(wù)啟動(dòng)和結(jié)束的時(shí)間來(lái)控制事務(wù)。
?啟動(dòng)事務(wù):使用 API 函數(shù)和 Transact-SQL 語(yǔ)句,可以按顯式、自動(dòng)提交或隱式的方式來(lái)啟動(dòng)事務(wù)。
?結(jié)束事務(wù):您可以使用 COMMIT(成功) 或 ROLLBACK(失敗) 語(yǔ)句,或者通過(guò) API 函數(shù)來(lái)結(jié)束事務(wù)。
?事務(wù)模式分為:顯示事務(wù)模式、隱式事務(wù)模式、自動(dòng)事務(wù)模式。在SQL常用的是顯示模式。
?事務(wù)并發(fā)處理會(huì)產(chǎn)生的問(wèn)題:
??1,丟失更新?
??當(dāng)兩個(gè)或多個(gè)事務(wù)選擇同一行,然后基于最初選定的值更新該行時(shí),會(huì)發(fā)生丟失更新問(wèn)題。?
??每個(gè)事務(wù)都不知道其它事務(wù)的存在。最后的更新將重寫由其它事務(wù)所做的更新,這將導(dǎo)致數(shù)據(jù)丟失。 ??
??2,臟讀?
??當(dāng)?shù)诙€(gè)事務(wù)選擇其它事務(wù)正在更新的行時(shí),會(huì)發(fā)生未確認(rèn)的相關(guān)性問(wèn)題。?
??第二個(gè)事務(wù)正在讀取的數(shù)據(jù)還沒(méi)有確認(rèn)并且可能由更新此行的事務(wù)所更改。
??3,不可重復(fù)讀?
??當(dāng)?shù)诙€(gè)事務(wù)多次訪問(wèn)同一行而且每次讀取不同的數(shù)據(jù)時(shí),會(huì)發(fā)生不一致的分析問(wèn)題。?
??不一致的分析與未確認(rèn)的相關(guān)性類似,因?yàn)槠渌聞?wù)也是正在更改第二個(gè)事務(wù)正在讀取的數(shù)據(jù)。?
??然而,在不一致的分析中,第二個(gè)事務(wù)讀取的數(shù)據(jù)是由已進(jìn)行了更改的事務(wù)提交的。而且,不一致的分析涉及多次(兩次或更多)讀取同一行,而且每次信息都由其它事務(wù)更改;因而該行被非重復(fù)讀取。?
??4,幻像讀?
??當(dāng)對(duì)某行執(zhí)行插入或刪除操作,而該行屬于某個(gè)事務(wù)正在讀取的行的范圍時(shí),會(huì)發(fā)生幻像讀問(wèn)題。?
??事務(wù)第一次讀的行范圍顯示出其中一行已不復(fù)存在于第二次讀或后續(xù)讀中,因?yàn)樵撔幸驯黄渌聞?wù)刪除。同樣,由于其它事務(wù)的插入操作,事務(wù)的第二次或后續(xù)讀顯示有一行已不存在于原始讀中。?
??事務(wù)的隔離級(jí)別
??該隔離級(jí)別定義一個(gè)事務(wù)必須與其他事務(wù)所進(jìn)行的資源或數(shù)據(jù)更改相隔離的程度。事務(wù)隔離級(jí)別控制:
??讀取數(shù)據(jù)時(shí)是否占用鎖以及所請(qǐng)求的鎖類型。
??占用讀取鎖的時(shí)間。
??引用其他事務(wù)修改的行的讀取操作是否:
???在該行上的排他鎖被釋放之前阻塞其他事務(wù)。
???檢索在啟動(dòng)語(yǔ)句或事務(wù)時(shí)存在的行的已提交版本。
???讀取未提交的數(shù)據(jù)修改。
?事務(wù)的隔離級(jí)別
??SQL語(yǔ)句可以使用SET TRANSACTION ISOLATION LEVEL來(lái)設(shè)置事務(wù)的隔離級(jí)別。
??1. Read Uncommitted:最低等級(jí)的事務(wù)隔離,僅僅保證了讀取過(guò)程中不會(huì)讀取到非法數(shù)據(jù)。上訴4種不確定情況均有可能發(fā)生。
??2. Read Committed:大多數(shù)主流數(shù)據(jù)庫(kù)的默認(rèn)事務(wù)等級(jí),保證了一個(gè)事務(wù)不會(huì)讀到另一個(gè)并行事務(wù)已修改但未提交的數(shù)據(jù),避免了“臟讀取”。該級(jí)別適用于大多數(shù)系統(tǒng)。
??第一個(gè)查詢事務(wù)
??SET? TRANSACTION? ISOLATION? LEVEL?? Read Committed
??begin? tran
?? update Cate SET Sname=Sname+'b' where ID=1
?? SELECT * FROM cate where ID=1
?? waitfor? delay? '00:00:6'??
?? rollback? tran??--回滾事務(wù)
??select Getdate()
??SELECT * FROM cate where ID=1
??第二個(gè)查詢事務(wù)
??SET? TRANSACTION? ISOLATION? LEVEL? Read committed?? --把committed換成Read uncommitted可看到“臟讀取”的示例。
??SELECT * FROM cate where ID=1
??select Getdate()
??可以看到使用 Read Committed 成功的避免了“臟讀取”.
??3. Repeatable Read:保證了一個(gè)事務(wù)不會(huì)修改已經(jīng)由另一個(gè)事務(wù)讀取但未提交(回滾)的數(shù)據(jù)。避免了“臟讀取”和“不可重復(fù)讀取”的情況,但是帶來(lái)了更多的性能損失。
??第一個(gè)查詢事務(wù)
??SET? TRANSACTION? ISOLATION? LEVEL? Repeatable Read? --?? 把Repeatable Read換成Read committed可以看到“不可重復(fù)讀取”的示例
??begin? tran
??SELECT * FROM cate where? ID=33?--第一次讀取數(shù)據(jù)
?? waitfor? delay? '00:00:6'??
??SELECT * FROM cate where? ID=33?--第二次讀取數(shù)據(jù),不可重復(fù)讀取
??commit
??第二個(gè)查詢事務(wù)
??SET? TRANSACTION? ISOLATION? LEVEL? Read committed
??update cate set Sname=Sname+'JD' where ID=33
??SELECT * FROM cate where ID>30
??4. Serializable:最高等級(jí)的事務(wù)隔離,上面3種不確定情況都將被規(guī)避。這個(gè)級(jí)別將模擬事務(wù)的串行執(zhí)行。
??在第一個(gè)查詢窗口執(zhí)行
??SET? TRANSACTION? ISOLATION? LEVEL? Serializable -- 把Serializable換成Repeatable Read 可看到“幻像讀”的示例
??begin? tran
??SELECT * FROM cate where ID>30?--第一次讀取數(shù)據(jù),“幻像讀”的示例
?? waitfor? delay? '00:00:6'?? --延遲6秒讀取
??SELECT * FROM cate where ID>30? --第一次讀取數(shù)據(jù)
??commit
??第二個(gè)查詢事務(wù)
??SET? TRANSACTION? ISOLATION? LEVEL? Read committed??
??Delete from cate where ID>33
??SELECT * FROM cate where ID>30??
創(chuàng)建事務(wù)
?設(shè)置事務(wù)級(jí)別:SET? TRANSACTION? ISOLATION? LEVEL
?開(kāi)始事務(wù):begin? tran
?提交事務(wù):COMMIT
?回滾事務(wù):ROLLBACK
?創(chuàng)建事務(wù)保存點(diǎn):SAVE TRANSACTION savepoint_name
?回滾到事務(wù)點(diǎn):ROLLBACK TRANSACTION savepoint_name
創(chuàng)建事務(wù)的原則:
盡可能使事務(wù)保持簡(jiǎn)短很重要,當(dāng)事務(wù)啟動(dòng)后,數(shù)據(jù)庫(kù)管理系統(tǒng) (DBMS) 必須在事務(wù)結(jié)束之前保留很多資源、以保證事務(wù)的正確安全執(zhí)行。
特別是在大量并發(fā)的系統(tǒng)中, 保持事務(wù)簡(jiǎn)短以減少并發(fā) 資源鎖定爭(zhēng)奪,將先得更為重要。
?1、事務(wù)處理,禁止與用戶交互,在事務(wù)開(kāi)始前完成用戶輸入。
?2、在瀏覽數(shù)據(jù)時(shí),盡量不要打開(kāi)事務(wù)
?3、盡可能使事務(wù)保持簡(jiǎn)短。
?4、考慮為只讀查詢使用快照隔離,以減少阻塞。
?5、靈活地使用更低的事務(wù)隔離級(jí)別。
?6、靈活地使用更低的游標(biāo)并發(fā)選項(xiàng),例如開(kāi)放式并發(fā)選項(xiàng)。
?7、在事務(wù)中盡量使訪問(wèn)的數(shù)據(jù)量最小。 ?
總結(jié)
以上是生活随笔為你收集整理的MSSQL事务开发指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 北方华创是芯片龙头吗 是半导体设备制造龙
- 下一篇: 在家开什么店又稳又能赚钱 推荐几个市场