记一次让人的喷血的排错经历
还原场景:
数据库某个字段设置的长度是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