B4J Question Avoid Duplicate Data on Server?

Harris

Expert
Licensed User
Longtime User
Using RDC.

I have several subs that insert new records into various tables.
After each batch is inserted, I invoke a ChecktoSend method which will send all new data.

The JobDone is responsible for determining if the data actually hit the server. If it did, it marks all records in the table as being SENT (then where sent = 1, records are deleted to keep bloat down).

The issue is, I use ChecktoSend in many areas. The results are the tables are delivered twice (maybe three time) and duplicate data is inserted because the JobDone had not returned from the first call to mark records as being SENT.

Question:
How would you make ChecktoSend wait until the first call had completed - before calling it again from another process?

Using B4A 6.30 (but have 7 ready to install).

B4X:
'  What I just did to combat these dups...

Sub ChecktoSend

' Sending var is a process_global

If Sending = False Then

    Sending = True      
    Select LogCM.CurrLogName

    Case "Shift Start", "Shift End", "On-Duty", "Log Out"
      ' ToastMessageShow(" Calling Update Server... "&LogCM.CurrLogName,False)

       AddLoadRecs
       AddTIRecs
       AddEvents
      ' AddLogRecs  ' moved to proper place
       AddScaleRecs
       AddShiftMast      
     
       If (LogCM.CurrLogName = "Shift End") Then
          CallSubDelayed(Me, "Backupfiles")
       End If
     
    End Select

End If

End Sub

Sub JobDone(Job As HttpJob)
'........ handle many results ........

     If result.Tag = "scale_mast" Then ' RDC query tag
        DefCM.SQL1.ExecNonQuery("UPDATE scalemast1 Set sent = 1 WHERE sent = 0")
        DefCM.SQL1.ExecNonQuery("DELETE FROM scalemast1 WHERE sent = 1") ' clean table
              
     End If      

' last lines...
    Job.Release
    LogServmod.Sending = False   ' safe to send again since above
  
End Sub

Thanks
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

Harris

Expert
Licensed User
Longtime User
Update your subs to use the new wait for.
Call a job, wait for the result. If success then do the next job.

https://www.b4x.com/android/forum/threads/b4x-okhttputils2-with-wait-for.79345/
Sweet... But I don't see how I can apply it to a RDC job. My task is a wee bit different (no simple download...).

Send scale records - if any...
B4X:
Sub AddScaleRecs
    
' MHW return for now while testing other mods in production
'Return
    
Dim i As Int
Dim c As Cursor
Dim commands As List
commands.Initialize   

If DefCM.Sql1.ExecQuerySingleResult("SELECT count(name) FROM sqlite_master WHERE type='table' AND name ='scalemast1'") = 0 Then
 ' do nothing cause no table built
Else
    Try
        c = DefCM.SQL1.ExecQuery("Select * from scalemast1 where sent = 0")

        For i = 0 To c.RowCount -1
           c.Position = i
           Dim cmd As DBCommand
           cmd.Initialize
           cmd.Name =  "scale_mast"
           cmd.Parameters = Array As Object(c.GetLong("pk"),c.GetInt("loadtype"),c.GetInt("acttype"),c.GetLong("recdate"),c.GetInt("drvid"),c.GetString("trkid"),c.GetString("trl1id"),c.GetString("trl2id"),c.GetString("trl3id"),c.GetLong("gross"),c.GetLong("tare"),c.GetString("rectype"),c.GetDouble("lat"),c.GetDouble("lon"),c.GetString("place"),c.GetInt("compid"),c.GetInt("sent"),c.GetDouble("odom"),c.GetDouble("fuel"),c.GetString("sourceid"),c.GetString("swver"),c.GetString("comment"))
          
           commands.Add(cmd)
           Log("added SCALE mast rec: "&i)

        Next

        c.Close

        If commands.Size > 0 Then
           LogCM.reqManager.myloadmast = commands
           LogCM.reqManager.mytagldmast = "scale_mast"
           LogCM.reqManager.IsConnectedLoadmast
        Else
         '   ToastMessageShow(" No Load Records to Send...",False)
        End If

    Catch
       Log("Table ScaleMast doesn't exist")
       If c.IsInitialized Then
         c.Close
       End If     

    End Try
End If


End Sub

Clean up when Job returns result
B4X:
            If result.Tag = "scale_mast" Then 'query tag
               DefCM.SQL1.ExecNonQuery("UPDATE scalemast1 Set sent = 1 WHERE sent = 0")
               DefCM.SQL1.ExecNonQuery("DELETE FROM scalemast1 WHERE sent = 1")
              
            End If
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
I've made an app that works like yours: local db that needs to upload data to a server and if success, update a local db field as sent; with DBRequestManagerWithResumableSubs is easy to implement.
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
I've made an app that works like yours: local db that needs to upload data to a server and if success, update a local db field as sent; with DBRequestManagerWithResumableSubs is easy to implement.
Encouraging...:)
 
Upvote 0
Top