Fork me on GitHub

记一次让人的喷血的排错经历

还原场景:

数据库某个字段设置的长度是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


 

posted @ 2018-04-05 19:01  迁梦余光  阅读(153)  评论(0编辑  收藏  举报