1. 程式人生 > >記一次讓人的噴血的排錯經歷

記一次讓人的噴血的排錯經歷

bmi ges brush sub 生成 www blog nsa size

還原場景:

數據庫某個字段設置的長度是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


記一次讓人的噴血的排錯經歷