▄︻┻┳═一「static」Agenda:
▄︻┻┳═一static,你还敢用吗?
▄︻┻┳═一static,你还敢用吗?(二)
▄︻┻┳═一【轻松一刻!】一段难倒了两名老程序猿的简单代码
昨天的代码改完之后,再次部署服务。今天检查日志却发现了新的bug——程序频报如下异常:
生成账单时异常:System.InvalidOperationException: The connection is not open.
根据异常堆栈信息定位到dal层方法:
public static bool Add(t_bills entity)
先贴出来相关代码吧:
1 public class BillsDal 2 { 3 static IDbConnection _conn /*= ConnUtility.GateWayConntion;*/ 4 { 5 get { return ConnUtility.GateWayConntion; } 6 } 7 static object syncRoot = new object(); 8 9 ///10 /// 插入记录(启用事务来处理主键BillId) 11 /// 12 /// 13 /// 14 public static bool Add(t_bills entity) 15 { 16 if (entity.CreatedTime == DateTime.MinValue) 17 { 18 entity.CreatedTime = DateTime.Now; 19 } 20 21 lock (syncRoot) 22 { 23 IDbConnection _conn = ConnUtility.GateWayConntion; 24 _conn.Open(); 25 var trans = _conn.BeginTransaction(); 26 try 27 { 28 var maxId = _conn.ExecuteScalar<long?>("SELECT MAX(BillId) FROM T_Bills;"); 29 if (maxId == null || maxId < CommonBase.BillId_DefaultValue) 30 { 31 maxId = CommonBase.BillId_DefaultValue; 32 } 33 entity.BillId = maxId.Value + 1; 34 35 long i = _conn.Insert<long>(entity, trans); 36 trans.Commit(); 37 i = 1; //执行Insert返回值是0,这里给1,以供下面的判断 38 return i > 0; 39 } 40 catch 41 { 42 trans.Rollback(); 43 throw; 44 } 45 finally 46 { 47 _conn.Close(); 48 } 49 } 50 } 51 }
经调试程序,发现执行var trans = _conn.BeginTransaction();这句时,报出了上面的异常:The connection is not open.
奇怪!前面一行代码是_conn.Open();呀,既然已经把连接打开了,怎么这里却提示“连接已关闭”呢?
我问旁边的同事,一个老程序猿,我跟他讲了昨天改动的原委,说_conn原来是这么定义的static IDbConnection _conn = ConnUtility.GateWayConntion;,后来改成了只读属性,即static IDbConnection _conn{get { return ConnUtility.GateWayConntion; }},执行这个Add方法就出现这个异常了。
我俩分析这段代码,你一言我一嘴的,讨论了有20分钟。
后来,
BTW,你看出来原因了吗?
后来,原因竟然是这个。。。
后来我的眼睛落在了var trans = _conn.BeginTransaction();的_conn上,猛然发现,是因为_conn.Open();里的_conn实例和var trans = _conn.BeginTransaction();里的_conn实例不是一个实例,因为每次调用只读属性拿到的都是一个新的实例。 然后。。。
然后,我给你讲个故事吧? 这个故事你可能听说过,也可能没听说过。
故事是:从前,有个人为了寻觅一种野草药,每天从山脚下爬到山上,苦苦寻觅,早出晚归。后来,他意外的发现,他所苦苦寻觅的野草药,就在他每日经过的山脚下。