日期:2014-05-18  浏览次数:20517 次

销售单据号重复问题
最近开发一套MIS,中间财务记录涉及到销售单据号的问题,因为页面试用了ViewState来存储临时表的方案,单据号我采用随机生成的数拼合而成,但依然在跨地区,多人同时操作时,偶尔产生单据号重复错误问题,我纳闷了很久,不知道是ViewState影响的?还是并发操作就算试用随机也会产生单据号重复?到此刻还未解决,寻求大家帮忙!
C# code
#region  重写加载视图状态方法
        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            //取得编辑前的datatable的视图状态   
            if (ViewState["TempClassList"] != null)
            {
                dt = (DataTable)ViewState["TempClassList"];
            }
        }
        #endregion

        #region  重写保存视图状态方法
        protected override object SaveViewState()
        {
            ViewState["TempClassList"] = dt;
            return base.SaveViewState();
        }
        #endregion

单据号产生方案如下:
/// <summary>
        /// 产生财务缴费流水号
        /// </summary>
        public string InitBarCode()
        {
            string id = "XS";
            Random r = new Random();
            id += DateTime.Now.Second.ToString().Length == 1 ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString() + r.Next(100000000).ToString();
            return id;
}




当然我其中需要先插入临时表中的数据,然后再插入财务销售收费记录,依然有发生单据号重复的几率,不知道什么原因?寻求高人指点。

------解决方案--------------------
你使用秒+随机数做单据号我觉得并不是很合理,秒的时间间隔只有一分钟,下一分钟就会出现重复,随机数也存在重复出现的概率,所以你这个方法即使不并发也会出现重复,相反,并发的时候在同一秒取数的概率不高,反而不会重复。建议单据号加上年月日,当然彻底排除并发仅靠单据号是无法解决的。
------解决方案--------------------
探讨
你使用秒+随机数做单据号我觉得并不是很合理,秒的时间间隔只有一分钟,下一分钟就会出现重复,随机数也存在重复出现的概率,所以你这个方法即使不并发也会出现重复,相反,并发的时候在同一秒取数的概率不高,反而不会重复。建议单据号加上年月日,当然彻底排除并发仅靠单据号是无法解决的。

------解决方案--------------------
随机数都伪随机,不保证完全一致。

销售单编号不能是完全随机的,市面上通常是机构编码+日期+当天序号。

生成编码的时候,要用个lock 来保证同一时刻只执行一次。

销售单是有主表和子表的,程序添加完主表以后就可以解锁了。速度是非常非常快的。
------解决方案--------------------
加年月日吧 光靠秒数太少了
------解决方案--------------------
在数据库中把单号做成唯一的键,在程序里面再做判断。
------解决方案--------------------
public string InitBarCode()
{
string id = "XS";
Random r = new Random();
id += DateTime.Now.Second.ToString().Length == 1 ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString() + r.Next(100000000).ToString();
return id;
}
===============================
这个代码的可靠性巨差。
多次调用 DateTime.Now.Second.ToString() 很可能最终是不一样的。
对DateTime 自带的函数非常不了解。
直接来个 DateTime.Now.ToString("ss");就完了。