cancel
Showing results for 
Search instead for 
Did you mean: 

dbremote sending update back to original db

bgreiman
Participant
1,879

We are using SQL Anywhere v12.01.4231

Here is update from remote database's translated log file:

--PUBLICATION-1101-010519954409401-0008-SUBSCRIBE
--PUBLICATION-1101-010519954409401-0023-SUBSCRIBE
--UPDATE-1101-010519954409401
UPDATE DBA.ps_customer_product_line
   SET modified_datetime='2016-11-04 11:36:27.29',
       modified_user='Kevinc',
       brand_description='LEINENKUGEL HONEY WEISS'
VERIFY (modified_datetime,
      modified_user,brand_description)
VALUES ('2016-04-12 16:22:12.734','Bills','LEINENKUGEL SUMMER SHANDY')
 WHERE company=3
   AND created_datetime='2010-12-31 11:24:28.0'
   AND created_user='Dellquist'

Here is update from translated log file when applied at consolidated database:

--PUBLICATION-1134-011136405404900-0003-SUBSCRIBE
--PUBLICATION-1134-011136405404900-0008-SUBSCRIBE
--PUBLICATION-1134-011136405404900-0023-SUBSCRIBE
--UPDATE-1134-011136405404900
UPDATE DBA.ps_customer_product_line
   SET modified_datetime='2016-11-04 11:36:27.29',
       modified_user='Kevinc',
       brand_description='LEINENKUGEL HONEY WEISS'
VERIFY (modified_datetime,
      modified_user,brand_description)
VALUES ('2016-04-12 16:22:12.734','Dbremote_new','LEINENKUGEL SUMMER SHANDY')
 WHERE company=3
   AND created_datetime='2010-12-31 11:24:28.0'
   AND created_user='Dellquist'

This particular statement was then replicated back to remote database. The issue is there were about 4 updates after this one that were applied at consolidated database (from remote) that did also not bounce back so that the data is now different between consolidate/remote. It is my understanding that statements should not bounce back to original sender. How does the system know to not send back and why did it send back this statement in this example?

Thanks, Brian Greiman

Accepted Solutions (0)

Answers (1)

Answers (1)

regdomaratzki
Product and Topic Expert
Product and Topic Expert

This is a classic SQL Remote problem that centers around conflict resolution. It is quite reasonable for an update to bounce back to the remote if a conflict occurs.

Let's imagine that at remote "X", my name is changed from "Reggie" to "Reg" and at the consolidated my name is changed from "Reggie" to "Reginald". SQL Remote runs at remote "X" and sends the change from Reggie->Reg. SQL Remote runs at the consolidated and applies the change, overwriting "Reginald". It detects a conflict, since the old value at the remote is not the same as the current value in the consolidated. SQL Remote now needs to send operations to all remote databases. Everybody except remote "X" will get two updates. The first update of Reggie->Reginald, and then the update of Reginald->Reg. However, the remote that sent the update of Reggie->Reg will only get one update (Reggie->Reginald), because updates sent from Remote "X" are not echoed back to Remote "X" (infinite loops are bad). This would result in all databases expect Remote "X" having a value of "Reg", but remote "X" would have a value of "Reginald". For this reason, updates ARE echoed back to the remote database if a conflict occurred when applying the change at the consolidated. This will result in all databases having "Reg" when they were done applying messages.

How this can get you into trouble :

Let's now imagine that remote "X" changes the row twice. Once from Reggie->Rig, then noticing the typo, from Rig->Reg. The consolidated database changes it from Reggie->Reginald. SQL remote is run at Remote "X" and then SQL Remote is run at the consolidated. The updates that are generate by SQL Remote always include a VERIFY clause that includes the old value at the remote, so that a conflict can be detected at the consolidated. The two updates will look like :

UPDATE customer SET firstName='Rig' VERIFY ('Reggie') where pkey=whatever;
UPDATE customer SET firstName='Reg' VERIFY ('Rig') where pkey=whatever;

When the first update in the message is applied, a conflict will be detected because the current value at the consolidated is 'Reginald', and not 'Reggie'. A conflict is flagged, and this update will be echoed back to remote "X". When the second update in the message is applied, no conflict is detected, because the old value at the remote was 'Rig' and the current value in the consolidated is 'Rig'. The second update is NOT echoed back to remote "X", resulting in inconsistent data in the databases.

How do you work around this issue :

If this is a serious issue for you, consider adding a column that is replicated that tracks the last time the row is modified, but don't just use "timestamp default timestamp" at the consolidated and remote. That's the default you should use at the remote, but not consolidated. If both defaults are the same, the default won't be used at the consolidated when applying messages, because the value is explicitly given in the update from the remote. Use a before update trigger to update this value at the consolidated instead.

CREATE TABLE admin (
  a_pkey bigint NOT NULL DEFAULT GLOBAL AUTOINCREMENT,
  textcol char(64) NULL,
  last_mod timestamp NULL default NULL,
  PRIMARY KEY (a_pkey)
);

create trigger au_admin before update on admin
referencing new as new_row for each row
begin
  set new_row.last_mod = CURRENT TIMESTAMP;
end;

Now, the second update in the message in the above scenario will also be flagged as an conflict, because the last_mod column does not match, as it was changed when the first update occurs.

Reg