码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-04-05 20:00:00      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:target   sql   file   字符串   分布式事务   原因   exception   tle   pos   

还原场景:

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


 

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

标签:target   sql   file   字符串   分布式事务   原因   exception   tle   pos   

原文地址:https://www.cnblogs.com/tianboblog/p/8723846.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!