【轻松一刻】一段难倒了两名老程序猿的简单代码

作者: buguge | 来源:发表于2017-01-06 14:21 被阅读624次

    昨天的代码改完之后,再次部署服务。今天检查日志却发现了新的bug——程序频报如下异常:

    生成账单时异常:System.InvalidOperationException: The connection is not open.#

    根据异常堆栈信息定位到dal层方法:

    public static bool Add(t_bills entity)

    先贴出来相关代码吧:

    public class BillsDal
    {
        static IDbConnection _conn /*= ConnUtility.GateWayConntion;*/
        {
            get { return ConnUtility.GateWayConntion; }
        }
        static object syncRoot = new object();
    
        /// <summary>
        /// 插入记录(启用事务来处理主键BillId)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool Add(t_bills entity)
        {
            if (entity.CreatedTime == DateTime.MinValue)
            {
                entity.CreatedTime = DateTime.Now;
            }
    
            lock (syncRoot)
            {
                IDbConnection _conn = ConnUtility.GateWayConntion;
                _conn.Open();
                var trans = _conn.BeginTransaction();
                try
                {
                    var maxId = _conn.ExecuteScalar<long?>("SELECT MAX(BillId) FROM T_Bills;");
                    if (maxId == null || maxId < CommonBase.BillId_DefaultValue)
                    {
                        maxId = CommonBase.BillId_DefaultValue;
                    }
                    entity.BillId = maxId.Value + 1;
    
                    long i = _conn.Insert<long>(entity, trans);
                    trans.Commit();
                    i = 1; //执行Insert返回值是0,这里给1,以供下面的判断
                    return i > 0;
                }
                catch
                {
                    trans.Rollback();
                    throw;
                }
                finally
                {
                    _conn.Close();
                }
            }
        }
    }
    

    经调试程序,发现执行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实例不是一个实例,因为每次调用只读属性拿到的都是一个新的实例。 然后。。。

    ......
    然后,我给你讲个故事吧? 这个故事你可能听说过,也可能没听说过。

    ......

    故事是:从前,有个人为了寻觅一种野草药,每天从山脚下爬到山上,苦苦寻觅,早出晚归。后来,他意外的发现,他所苦苦寻觅的野草药,就在他每日经过的山脚下。

    【轻松一刻!】一段难倒了两名老程序猿的简单代码

    相关文章

      网友评论

      本文标题:【轻松一刻】一段难倒了两名老程序猿的简单代码

      本文链接:https://www.haomeiwen.com/subject/xxztbttx.html