為什麼事務沒有回滾!

来源:http://www.cnblogs.com/i6first/archive/2016/03/31/5342080.html
-Advertisement-
Play Games

--事務的原子性要求事務要麼全部完成,要麼全部不完成,不可能停滯在某個中間狀態。--然而,我的事務卻沒有“回滾”,為此還導致了異常數據的發生,為什麼? 這是一個發生在我工作中的真實的案例,在用戶問我的時候我當時也SB了,在我理解了這背後的原理後,我雖然接受了SQL Server在某些場景下不回滾的設 ...


--事務的原子性要求事務要麼全部完成,要麼全部不完成,不可能停滯在某個中間狀態。
--然而,我的事務卻沒有“回滾”,為此還導致了異常數據的發生,為什麼?

這是一個發生在我工作中的真實的案例,在用戶問我的時候我當時也SB了,
在我理解了這背後的原理後,我雖然接受了SQL Server在某些場景下不回滾的設計使然,但不得不吐槽,這個功能真不爽!
下麵我利用一個樣例來描述這個問題:

--創建test1表
CREATE TABLE [dbo].[test1](
    [id] [int] NOT NULL,
    [testname] [varchar](10) NULL
) ON [PRIMARY]
GO

現在執行一個事務,事務中包含兩個insert操作,其中第一個insert操作的testname欄位超過了最大長度10

--顯示執行一個事務,插入兩行數據,其中第一行的testname欄位超過了最大長度

         BEGIN TRANSACTION;
         --SELECT 1
         --FROM test;
         INSERT INTO [dbo].[test1]
                                  ([id], [testname]
                                  )
         VALUES
                (1, '123456789101'
                );
         INSERT INTO [dbo].[test1]
                                  ([id], [testname]
                                  )
         VALUES
                (888, '12345'
                );
         COMMIT TRANSACTION;

如預料的一樣,SQL Server在執行第一條語句時報錯

image

“按理”說來,這個事務執行會失敗,第二條插入語句會回滾,但實際結果卻是:

select * from [dbo].[test1]

image

在某些場景下,這會導致異常數據的發生。

 

為什麼會這樣呢??

據MSDN,預設情況,SQL Server並不會回滾事務,即使事務中的某個語句報錯,事務還是會繼續執行下去,除非非常嚴重的錯誤(serverity level is greater or equals 16)。
這是由資料庫選項XACT_ABORT決定的,預設XACT_ABORT為OFF,

When SET XACT_ABORT is OFF, in some cases only the Transact-SQL statement that raised the error is rolled back and the transaction continues processing. Depending upon the severity of the error, the entire transaction may be rolled back even when SET XACT_ABORT is OFF. OFF is the default setting.

如果想規避這個問題,微軟告訴我們需要把XACT_ABORT設置為On,這樣一個事務中任務一個語句報錯都會導致整個事務回滾。

SET XACT_ABORT ON

當然,你也可以使用try、catch人工捕獲錯誤以便進行回滾或者在程式中使用事務。

 

我在想為什麼會有這麼DT的設計呢?

我們學事務的第一堂課裡面就講了事務的原子性要求:事務要麼全部執行,要麼全部失敗,不會存在中間狀態。
但SQL Server為什麼預設不回滾呢?百思不得其解。
求助MSDN時鄒大俠給的一個解釋雖然有道理(謝謝鄒大俠),但還是覺得不夠完美,因為即使是為了能夠讓開發人員自己來控制事務的狀態,也不應該把XACT_ABORT預設設置為OFF,相反,如果設置為On倒是可以接受。

 

image

 

期待其他大神們給予指導。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 從昨天下午接到新任務,要採集一個法院網站得所有公告,大概是需要採集這個網站得所有公告列表裡得所有txt內容,txt文件裡邊是一件件赤裸裸得案件,記錄這案由,原告被告等相關屬性(不知道該叫什麼就稱之為屬性吧,汗),把這些文件放到本地某個目錄,並把一個案件作為一條數據放入資料庫中。本以為很輕鬆得用Jso ...
  • 問題場景 最近在項目中遇到了對每一個類型進行求和並且求該類型所占的比例,當時考慮求出每種類型的和,併在java中分別對每一種類型的和與總和相除求出所占比例。後來,想到這樣有點麻煩,並且項目中持久層使用的是iBatis框架,所有考慮從SQL方面進行入手來簡化這個問題。 後來SQL的解決方法就為: 看到 ...
  • 一、主鍵自增長: 1) oracle: 使用序列實現,比如創建序列,起點是1000,步進是1: create sequence myseq increment by 1 start with 1000 增加記錄: insert into student(stuId,stuName) values(m ...
  • 1.Question Description: 1.1 version: mysql-5.7.11-64 1.2 form: zip file 1.3 >mysqld --install (successfully) 1.4 you create a directory called "data" ...
  • 子查詢在一個select中出現多個嵌套查詢語句 1、在where子句中使用子查詢(一般返回"單行單列" "單行多列" "多行單列"(可以提供in、any、all )) 示例1:查找低於平均工資的雇員信息(返回單行單列) 示例2:查找出公司最早雇佣的雇員信息(返回單行單列) 示例3:與scott從事同 ...
  • 一、起因 begin或者START TRANSACTION開始一個事務 rollback事務回滾 commit 事務確認 人們對事務的解釋如下:事務由作為一個單獨單元的一個或多個SQL語句組成,如果其中一個語句不能完成,整個單元就會回滾(撤銷),所有影響到的數據將返回到事務開始以前的狀態。因而,只有 ...
  • 介紹 正則表達式用來描述或者匹配符合規則的字元串。它的用法和like比較相似,但是它又比like更強大,能夠實現一些很特殊的規則匹配;正則表達式需要使用REGEXP命令,匹配上返回"1"匹配不上返回"0",REGEXP相當於like '%%'。 命令 說明 ^ 在字元的開啟處進行匹配 $ 在字元的末 ...
  • 修改ibdata1大小的驗證 ibdata是共用表空間,在MySQL初始化的時候就生成了。 但很多童鞋會看到網上各種大神的調優建議,在MySQL已經初始化的情況下,修改配置文件中innodb_data_file_path=ibdata1:12M:autoextend。導致MySQL啟動的時候報錯。 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...