記一次讓人的噴血的排錯經歷
還原場景:
數據庫某個字段設置的長度是nvchar(10),可當時並不知曉啊......結果導致下單接口返回“將截斷字符串或二進制數據”,查了半天(下單參數實在太多)最終追蹤到某個字段長度不夠導致.....
因為內部有異常捕獲,所以調用方拿到了錯誤消息!但更詭異的是:竟然生成了訂單數據,只不過字段不夠的那張表失敗了......
模擬代碼:
try { using (DataClasses1DataContext db = new DataClasses1DataContext()) { T_Classes cs = new T_Classes() { CName = "班級2" }; T_Users user = new T_Users() { UName = "小明2", Age = 10 }; db.T_Classes.InsertOnSubmit(cs); db.T_Users.InsertOnSubmit(user); db.SubmitChanges(); } } catch (Exception ex) { }
Linq to sql 一次SubmitChange怎麽沒有rollback呢?也很久不用這個玩意了,我印象中一次SubmitChange就是獨立的一個事務單元,可這是怎麽回事?百思不得其解,搞得我都有點懷疑人生......
於是開始使用SQL Server Profiler追蹤SubmitChange之後最終執行的sql如下:
看了之後又是顛覆了我的三觀,為什麽沒有Transcation,難道真的是我記錯了......
嘗試把第二個對象某個屬性賦值超過數據庫字段長度,看第一個是否可以正常插入還是一起回滾:
try { using (DataClasses1DataContext db = new DataClasses1DataContext()) { T_Classes cs = new T_Classes() { CName = "班級2" }; T_Users user = new T_Users() { UName = "小明21111111111111111111111111111111111111111111111111", Age = 10 }; db.T_Classes.InsertOnSubmit(cs); db.T_Users.InsertOnSubmit(user); db.SubmitChanges(); } } catch (Exception ex) { }
結果還是回滾了,也證明一次SubmitChanges就是獨立的事務。但是為什麽在SQL Server Profiler中追蹤到的sql看不到事務相關信息啊?我的環境是(SqlServer2008 + VS2013)知道的可以留言賜教!多謝!
經過以上驗證,雖然沒有直觀看到事務,不過從最終的結果看確實是有事務的!但為什麽出現下單“將截斷字符串或二進制數據”?開始檢查代碼的前後調用流程,最終在發現一個雷:在父類中開啟了一個分布式事務,還原整個代碼情形意思如下:
using (TransactionScope tran = new TransactionScope()) { try { using (DataClasses1DataContext db = new DataClasses1DataContext()) { T_Classes cs = new T_Classes() { CName = "班級2" }; T_Users user = new T_Users() { UName = "小明2111111111111111111111111", Age = 10 }; db.T_Classes.InsertOnSubmit(cs); db.T_Users.InsertOnSubmit(user); db.SubmitChanges(); } } catch (Exception ex) { } tran.Complete(); }
其原因顯而易見了,SubmitChanges沒有提交成功,TransactionScope中Complete提交了!
關於TransactionScope
https://www.cnblogs.com/liuyl/p/4300652.html
http://www.cnblogs.com/artech/archive/2010/01/31/1660356.html
記一次讓人的噴血的排錯經歷