none
请教一个程序设计的思路问题! RRS feed

  • 问题

  • 现在本地有一个假设的表(table):

    id,user,sex,date,ip,zhuangt......

    0,123,男,2012-06-07,127.0.0.1,未提交.......

    1,333,女,2012-06-07,127.0.0.1,未提交.......

    2,222,男,2012-06-07,127.0.0.1,未提交.......

    ...................

    这个表每天可能有上万、上十万行新数据产生,通过本地的windows服务每10秒读取一次数据库把这些数据上传到服务器端(服务器端没有开放1433,只提交了webservice来接收这些数据,webservice每次只允许请求1000行数据)

    部分代码:

                string conn = "数据库连接";
                string sql = "select top 5000 * from table where zhuangt='未提交'";
                SqlConnection cn = new SqlConnection(conn);
                cn.Open();
                SqlDataAdapter adapt = new SqlDataAdapter(sql, cn);
                DataSet ds = new DataSet();
                adapt.Fill(ds, "sms_sendlog");
                if (ds.Tables[0].Rows.Count != 0)
                {
                    string s = "0";
                    string sqlid = "Update table set zhuangt='已提交' where";
                    string id = "";
                    for (int i = 1; i <= ds.Tables[0].Rows.Count; i++)
                    {
                        id += " id=" + ds.Tables[0].Rows[i - 1][0].ToString() + " or";
                        if (i % 1000 == 0)
                        {
                            try
                            {
                                if (s = "0")
                                {
                                    s = "调用webservice的返回值";
                                    if (s = "0")
                                    {
                                        sqlid += id.Substring(0, id.Length - 3);
                                        SqlCommand com = new SqlCommand(sqlid, cn);
                                        com.ExecuteNonQuery();
                                    }
                                }
                                sqlid = "Update table set zhuangt='已提交' where";
                                id = "";
                            }
                            catch (Exception ex)
                            {
                            }
                        }
                    }
                    if (id != "")
                    {
                        try
                        {
                            if (s = "0")
                            {
                                s = "调用webservice的返回值";
                                if (s = "0")
                                {
                                    sqlid += id.Substring(0, id.Length - 3);
                                    SqlCommand com = new SqlCommand(sqlid, cn);
                                    com.ExecuteNonQuery();
                                }
                            }
                            sqlid = "Update table set zhuangt='已提交' where";
                            id = "";
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                    cn.Close();
                }

    以上是部分代码,写的windows服务是每10秒读取一次数据库的数据,当webservice返回值慢的时候本地的服务就会出现并发的情况(可能有朋友会说把读取的时间修改长一点),出现重复提交数据,请教下有什么方法能避免这样的并发出现同时提交数据的效率也会比较高。
    2012年6月7日 7:35

答案

  • 不是修改读取出来的数据的标记,

    这个标记是用了标记这个服务的的。和你要操作的数据没有关系。

    如果这个标记为0,表示上一轮操作数据完成。

    如果这个标记为1,表示上一轮数据还没有操作完成,就不要进行下一轮操作了


    http://blog.csdn.net/zx13525079024

    2012年6月8日 10:24
  • 做一个Windows服务,里面保存着一个全局变量,比如flag,然后就像 开心大侠说的

    “这个标记是用了标记这个服务的的。和你要操作的数据没有关系。
     
    如果这个标记为0,表示上一轮操作数据完成。
     
    如果这个标记为1,表示上一轮数据还没有操作完成,就不要进行下一轮操作了”

    因为Windows服务你可以配置为开机就立刻运行,一直运行到关机,所以可以在Windows服务里写一些代码逻辑去判断数据的操作


    给我写信: QQ我:点击这里给我发消息

    2012年6月8日 16:06

全部回复

  • 可以这样,每次服务开始操作数据的时候设置一个标记,这个标记可以在数据库中设置

    你的服务每隔10运行一次,

    当操作数据前,更新标记为1

    操作数据完成后,更新标记为0,

    每次操作数据的时候,先判断,如果标记为1,表示上一轮服务没有执行完成,当前这轮暂不读取数据操作。这样就不会造成并发

     


    http://blog.csdn.net/zx13525079024

    2012年6月7日 9:45
  • 您是说在table 表中添加一个字段作为标记字段吗? 这样会不会要多次操作数据库? 希望您能给出 部分代码  谢谢!
    2012年6月7日 23:28
  • 可以将这个标记存储到数据库里面,也可以存储到其他地方。

    if(判断标记是否为0)

    {

       //如果为0执行数操作

         try

       {

                 1.更改标记为1

                 2.执行数据操作.

        }

    catch

    {

    }

    finally

    {

         3. 更改标记为0

    }

    }


    http://blog.csdn.net/zx13525079024

    2012年6月8日 1:36
  • 您好!您的意思是读取数据之前把已读取的数据标记修改为1,然后再提交数据。这样两次操作数据库会不会比较麻烦?能否在数据第一读出来的时候就同时修改标记字段状态一次完成?不知道通过sql能否实现?


    • 已编辑 yyyukai 2012年6月8日 2:36
    2012年6月8日 2:35
  • 我们系统也是做成Windows服务,逻辑跟你差不多,使用C#来做的,也是要同步数据跟公网上的服务器,可惜代码不在我手上,不好意思LZ

    给我写信: QQ我:点击这里给我发消息


    2012年6月8日 7:38
  • 首先这样操作不会麻烦,就是你多加个判断,多写行代码,

    其次这也不会对数据库造成太大的压力影响。

    再次,如果判断发现数据库中的标记不为0,就不用读取数据了。也就不用操作数据库数据了


    http://blog.csdn.net/zx13525079024

    2012年6月8日 8:31
  • 判断问题是不大   就是在第一次读取数据的时候 这些读取出来的数据需要修改标记!
    2012年6月8日 8:52
  • 不是修改读取出来的数据的标记,

    这个标记是用了标记这个服务的的。和你要操作的数据没有关系。

    如果这个标记为0,表示上一轮操作数据完成。

    如果这个标记为1,表示上一轮数据还没有操作完成,就不要进行下一轮操作了


    http://blog.csdn.net/zx13525079024

    2012年6月8日 10:24
  • 做一个Windows服务,里面保存着一个全局变量,比如flag,然后就像 开心大侠说的

    “这个标记是用了标记这个服务的的。和你要操作的数据没有关系。
     
    如果这个标记为0,表示上一轮操作数据完成。
     
    如果这个标记为1,表示上一轮数据还没有操作完成,就不要进行下一轮操作了”

    因为Windows服务你可以配置为开机就立刻运行,一直运行到关机,所以可以在Windows服务里写一些代码逻辑去判断数据的操作


    给我写信: QQ我:点击这里给我发消息

    2012年6月8日 16:06