mirror of
https://github.com/google/nomulus.git
synced 2025-08-12 20:49:37 +02:00
Improve Transaction gap processing (#1546)
Skip multiple gaps in one pass and write the correct transaction id to datastore.
This commit is contained in:
parent
8db28b7e61
commit
71d13bab71
2 changed files with 24 additions and 16 deletions
|
@ -127,12 +127,16 @@ public class ReplicateToDatastoreAction implements Runnable {
|
||||||
// Reload the last transaction id, which could possibly have changed.
|
// Reload the last transaction id, which could possibly have changed.
|
||||||
LastSqlTransaction lastSqlTxn = LastSqlTransaction.load();
|
LastSqlTransaction lastSqlTxn = LastSqlTransaction.load();
|
||||||
long nextTxnId = lastSqlTxn.getTransactionId() + 1;
|
long nextTxnId = lastSqlTxn.getTransactionId() + 1;
|
||||||
if (nextTxnId < txnEntity.getId()) {
|
|
||||||
// Missing transaction id. This can happen normally. If a transaction gets
|
// Skip missing transactions. Missed transactions can happen normally. If a
|
||||||
// rolled back, the sequence counter doesn't.
|
// transaction gets rolled back, the sequence counter doesn't.
|
||||||
|
while (nextTxnId < txnEntity.getId()) {
|
||||||
logger.atWarning().log(
|
logger.atWarning().log(
|
||||||
"Ignoring transaction %s, which does not exist.", nextTxnId);
|
"Ignoring transaction %s, which does not exist.", nextTxnId);
|
||||||
} else if (nextTxnId > txnEntity.getId()) {
|
++nextTxnId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextTxnId > txnEntity.getId()) {
|
||||||
// We've already replayed this transaction. This shouldn't happen, as GAE cron
|
// We've already replayed this transaction. This shouldn't happen, as GAE cron
|
||||||
// is supposed to avoid overruns and this action shouldn't be executed from any
|
// is supposed to avoid overruns and this action shouldn't be executed from any
|
||||||
// other context, but it's not harmful as we can just ignore the transaction. Log
|
// other context, but it's not harmful as we can just ignore the transaction. Log
|
||||||
|
|
|
@ -208,18 +208,20 @@ public class ReplicateToDatastoreActionTest {
|
||||||
TestObject foo = TestObject.create("foo");
|
TestObject foo = TestObject.create("foo");
|
||||||
insertInDb(foo);
|
insertInDb(foo);
|
||||||
|
|
||||||
// Fail during the transaction to delete it.
|
// Fail two transactions.
|
||||||
try {
|
for (int i = 0; i < 2; ++i) {
|
||||||
jpaTm()
|
try {
|
||||||
.transact(
|
jpaTm()
|
||||||
() -> {
|
.transact(
|
||||||
jpaTm().delete(foo.key());
|
() -> {
|
||||||
// Explicitly save the transaction entity to force the id update.
|
jpaTm().delete(foo.key());
|
||||||
jpaTm().insert(new TransactionEntity(new byte[] {1, 2, 3}));
|
// Explicitly save the transaction entity to force the id update.
|
||||||
throw new RuntimeException("fail!!!");
|
jpaTm().insert(new TransactionEntity(new byte[] {1, 2, 3}));
|
||||||
});
|
throw new RuntimeException("fail!!!");
|
||||||
} catch (Exception e) {
|
});
|
||||||
logger.atInfo().log("Got expected exception.");
|
} catch (Exception e) {
|
||||||
|
logger.atInfo().log("Got expected exception.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestObject bar = TestObject.create("bar");
|
TestObject bar = TestObject.create("bar");
|
||||||
|
@ -230,11 +232,13 @@ public class ReplicateToDatastoreActionTest {
|
||||||
assertThat(txns).hasSize(2);
|
assertThat(txns).hasSize(2);
|
||||||
for (TransactionEntity txn : txns) {
|
for (TransactionEntity txn : txns) {
|
||||||
assertThat(txn.getId()).isNotEqualTo(2);
|
assertThat(txn.getId()).isNotEqualTo(2);
|
||||||
|
assertThat(txn.getId()).isNotEqualTo(3);
|
||||||
applyTransaction(txn);
|
applyTransaction(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(foo.key()))).isEqualTo(foo);
|
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(foo.key()))).isEqualTo(foo);
|
||||||
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(bar.key()))).isEqualTo(bar);
|
assertThat(ofyTm().transact(() -> ofyTm().loadByKey(bar.key()))).isEqualTo(bar);
|
||||||
|
assertThat(ofyTm().transact(() -> LastSqlTransaction.load()).getTransactionId()).isEqualTo(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue