Foxtable(狐表)用户栏目专家坐堂 → 请问我这里有代码会导致行重复新建吗?


  共有2791人关注过本帖树形打印复制链接

主题:请问我这里有代码会导致行重复新建吗?

帅哥哟,离线,有人找我吗?
chen37280600
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1279 积分:7953 威望:0 精华:4 注册:2017/12/31 14:53:00
请问我这里有代码会导致行重复新建吗?  发帖心情 Post By:2018/10/5 10:40:00 [只看该作者]

系统使用了大半年,新建了5000多条数据,偶尔一两次发现,新建行的时候会重复新建2条一模一样的行,不过_identify 是不一样的。非常罕见,大概1000行里会出现1次。客户的网络环境也不太好,是个垃圾的移动。服务器是深圳的阿里云

 

 错误效果:

 
此主题相关图片如下:1.png
按此在新窗口浏览图片 

重复错误的主要体现:CarFixID和CarFixTime完全一样。因为这2个都是通过HttpClient从服务器获取的网络环境下的自动编号与时间

 

请问下面代码,是否有会导致重复新建的可能性?

 

①窗口的新建行按钮:先判断能否成功获取自动编号,成功后再显示编辑窗口

If Functions.Execute("GetNewRow","CarFixID","CarFixInfo") Then
    Forms("CarFixEdit").show 
    Tables("CarFixInfo").AutoSizeCols

End If

 

②内部函数GetNewRow:给5秒的时候系统去获取最新编号,如果获取成功就继续,不成功,就RejectChanges

Dim NewID As String = args(0)'传递id的名字CarID
Dim TableName As String = args(1)'传递要新增行的Table的名字


Dim t As Table = Tables(TableName)
Dim r As Row = t.AddNew
Dim dn As Date = Date.Now
Do While Date.Now < dn.AddSeconds(5)
    If r.IsNull(NewID) = False Then
        Exit Do
    End If
    Application.DoEvents
Loop
If r.IsNull(NewID)=False Then
    Return True
Else
    t.DataTable.RejectChanges
    MessageBox.show("1连接服务器失败,网络不稳定,请重试!")
    Return False
End If

 

③DataRowAdding事件:调用GetNewID的内部函数去获取新ID,时间是通过内部函数,获取服务器上的时间,防止作弊

Dim NewID As Integer =  Functions.Execute("GetNewID","CarFixID")
If NewID > -1 Then
    e.DataRow("CompanyID") = PublicCompanyID
    e.DataRow("CarFixID") = NewID
    e.DataRow("CarFixUser") = PublicMHUserID
    e.DataRow("CarFixTime") = Functions.Execute("SqlDate")
    e.DataRow("CarFixStatus") = 1
End If

 

 

④内部函数GetNewID:使用HttpClient的方法,去获取最新编号,限制5秒超时

Dim s As String = args(0)'传递要获取的ID名,例如CarID

'HttpClient网络自动编号-----
Dim sWeb As String = DecryptText(SSL_ServerWeb,"cjj","xt")
Dim hc As New HttpClient(sWeb & "GetNewID.htm")
hc.Timeout = 5 '设置超时为5秒
hc.C & s & "f:"
Dim rt As String = hc.GetData()
Dim id As Integer
If rt > "" Then
    If  Integer.TryParse(rt,id)  Then
        Return id
    Else
        messagebox.show("服务器返回错误信息:" & rt)
        Return -1
    End If
Else
    messagebox.show("3连接服务器失败,网络不稳定,请重试!")
    Return -1
End If

 

④内部函数SqlDate(它在刚才的错误截图里,我们看到2个重复行的时间是完全一样的,说明这并不是系统重复新建了2次,如果是重复新建,那时间肯定不一样

'防止时间作弊,直接获取服务器时间-----
'无需传递参数
Dim cmd As New SQLCommand
Dim dt As Date
cmd.C
cmd.CommandText = "Select GetDate()"
dt = cmd.ExecuteScalar()
Return dt


[此贴子已经被作者于2018/10/5 10:41:54编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2018/10/5 10:53:00 [只看该作者]

你直接测试这个函数即可 Dim NewID As Integer =  Functions.Execute("GetNewID","CarFixID")

 

比如循环100次或者1000次,或者打开多个客户端,一起模拟循环多次测试请求,看是否重复。如果重复,就是你服务器端没有处理好导致的。


 回到顶部
帅哥哟,离线,有人找我吗?
chen37280600
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1279 积分:7953 威望:0 精华:4 注册:2017/12/31 14:53:00
  发帖心情 Post By:2018/10/5 11:48:00 [只看该作者]

我在服务器端的提供编号的代码

httpRequest放了内部函数GetNewID,代码如下

 

Dim e As RequestEventArgs = args(0)
If e.PlainText > "" Then
    Dim msg As String = e.PlainText
   
    '网络自动编号--------标志:f
    If msg.StartsWith(":f") AndAlso msg.EndsWith("f:") Then
        msg = msg.SubString(2, msg.Length - 4) '注意截取位数的关系
        If CodeDic.ContainsKey(msg) Then '如果存在这个类别的编号,msg传回来是一个自己约定的编号,例如  ItemBrandNo
            CodeDic(msg) = CodeDic(msg) + 1 '将该类别最大编号加1
        Else
            CodeDic.Add(msg,1) '如果是这个列表的首次编号,则编号等于1
        End If
        e.WriteString(CodeDic(msg)) '将编号返回给客户端
    End If
    '网络自动编号---------标志:f
   
End If
Return True

 

这个基本都是按照官方说明文档。

 

还有一个很关键的,这套自动编号代码,我已经用过在16个项目,超过100个表,完全一样的代码,改几个关键字而已。他们都稳定使用。


 回到顶部
帅哥哟,离线,有人找我吗?
chen37280600
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1279 积分:7953 威望:0 精华:4 注册:2017/12/31 14:53:00
  发帖心情 Post By:2018/10/5 12:00:00 [只看该作者]

循环了1000次,没有重复值。

我的跟服务器网络都很稳定

 

客户是移动的,他网络不怎么稳定的


 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2018/10/5 12:21:00 [只看该作者]

以下是引用chen37280600在2018/10/5 12:00:00的发言:

循环了1000次,没有重复值。

我的跟服务器网络都很稳定

 

客户是移动的,他网络不怎么稳定的

 

打开多个客户端,多个客户端同时一起循环获取,是否重复?如果不重复,说明没问题。


 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2018/10/5 12:22:00 [只看该作者]

以下是引用有点甜在2018/10/5 12:21:00的发言:

 

打开多个客户端,多个客户端同时一起循环获取,是否重复?如果不重复,说明没问题。

 

或者是弄异步函数,异步执行获取,看是否重复

 

http://www.foxtable.com/mobilehelp/scr/3269.htm

 


 回到顶部
帅哥哟,离线,有人找我吗?
chen37280600
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1279 积分:7953 威望:0 精华:4 注册:2017/12/31 14:53:00
  发帖心情 Post By:2018/10/24 14:21:00 [只看该作者]

我测试了很多次,我已经确定,不是有行新建的时候触发的错误。

 

原因

1我用异步大量获取,没有重复问题

2这个获取ID的方法,我已经在16个项目里用过,都稳定

3我特意加了一个日期字段,在DatarowAdding里设置  RowAddTime = Date.now

 

然后我还是可以发现有重复的行,而且行的RowAddTime是完全完全一样,精确到毫秒。

 

如果连续新建行,不可能连毫秒都能达到一样,没可能这么准确。

 

所以我怀疑是保存的时候会导致重复行。

 

请问狐表是否可能在网络不稳定,不太好的情况下,帮我重复保存行?

[此贴子已经被作者于2018/10/24 14:22:56编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2018/10/24 14:42:00 [只看该作者]

1、你服务器上的 GetNewID.htm 处理函数,是同步调用还是异步调用?不能异步调用。

 

2、模拟测试的时候,你要用多个客户端,异步操作模拟,甚至用多台电脑多个客户端一起异步操作。


 回到顶部
帅哥哟,离线,有人找我吗?
chen37280600
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:六尾狐 帖子:1279 积分:7953 威望:0 精华:4 注册:2017/12/31 14:53:00
  发帖心情 Post By:2018/10/24 14:58:00 [只看该作者]

1服务器的GetNewID是同步的

 

2我发现也不需要多台客户端测试,因为真的很容易就出现,我看到好几条重复的数据,创建人都是一样的,就一个电脑就能产生,实在是太奇怪了。

明明我也没有做 过r1(RowAddTime)=r2(RowAddTime)的代码,怎么可能完全一样。与RowAddTime相关的代码,也只有在DatarowAdding的时候赋值Date.now


 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2018/10/24 15:13:00 [只看该作者]

以下是引用chen37280600在2018/10/24 14:58:00的发言:

 

我发现也不需要多台客户端测试,因为真的很容易就出现,我看到好几条重复的数据,创建人都是一样的,就一个电脑就能产生,实在是太奇怪了。

 

 

如何模拟测试可以出现问题?

 

修改你【GetNewRow】事件的代码,不要用那种addnew然后reject的方式检测。而是应该先去获取id号,能获取到以后,再addnew和赋值保存等。

 

而且尽量不要用 Do While Date.Now < dn.AddSeconds(5)


 回到顶部
总数 14 1 2 下一页