Skip to content

Commit 349f3b0

Browse files
schmidt-sebastianpongad
authored andcommitted
Firestore: Adding a transaction test with contention (#2532)
1 parent 87dd418 commit 349f3b0

1 file changed

Lines changed: 47 additions & 19 deletions

File tree

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static org.junit.Assert.assertTrue;
2424
import static org.junit.Assert.fail;
2525

26+
import com.google.api.core.ApiFuture;
2627
import com.google.api.core.ApiFutures;
2728
import com.google.cloud.firestore.CollectionReference;
2829
import com.google.cloud.firestore.DocumentReference;
@@ -47,7 +48,9 @@
4748
import java.util.Iterator;
4849
import java.util.List;
4950
import java.util.Map;
51+
import java.util.concurrent.CountDownLatch;
5052
import java.util.concurrent.ExecutionException;
53+
import java.util.concurrent.atomic.AtomicInteger;
5154
import org.junit.Before;
5255
import org.junit.Rule;
5356
import org.junit.Test;
@@ -425,25 +428,50 @@ public String updateCallback(Transaction transaction) {
425428
}
426429

427430
@Test
428-
public void successfulTransaction() throws Exception {
429-
final DocumentReference documentReference = addDocument("foo", 1);
430-
431-
String result =
432-
firestore
433-
.runTransaction(
434-
new Transaction.Function<String>() {
435-
@Override
436-
public String updateCallback(Transaction transaction)
437-
throws ExecutionException, InterruptedException {
438-
DocumentSnapshot documentSnapshot = documentReference.get().get();
439-
documentReference.update("foo", documentSnapshot.getLong("foo") + 1);
440-
return "bar";
441-
}
442-
})
443-
.get();
444-
445-
assertEquals("bar", result);
446-
assertEquals(2L, documentReference.get().get().get("foo"));
431+
public void successfulTransactionWithContention() throws Exception {
432+
final DocumentReference documentReference = addDocument("counter", 1);
433+
434+
final CountDownLatch latch = new CountDownLatch(2);
435+
final AtomicInteger attempts = new AtomicInteger();
436+
437+
// One of these transaction fails and has to be retried since they both acquire locks on the
438+
// same document, which they then modify.
439+
ApiFuture<String> firstTransaction =
440+
firestore.runTransaction(
441+
new Transaction.Function<String>() {
442+
@Override
443+
public String updateCallback(Transaction transaction)
444+
throws ExecutionException, InterruptedException {
445+
attempts.incrementAndGet();
446+
DocumentSnapshot documentSnapshot = transaction.get(documentReference).get();
447+
latch.countDown();
448+
latch.await();
449+
transaction.update(documentReference,
450+
"counter", documentSnapshot.getLong("counter") + 1);
451+
return "foo";
452+
}
453+
});
454+
455+
ApiFuture<String> secondTransaction =
456+
firestore.runTransaction(
457+
new Function<String>() {
458+
@Override
459+
public String updateCallback(Transaction transaction)
460+
throws ExecutionException, InterruptedException {
461+
attempts.incrementAndGet();
462+
DocumentSnapshot documentSnapshot = transaction.get(documentReference).get();
463+
latch.countDown();
464+
latch.await();
465+
transaction.update(documentReference,
466+
"counter", documentSnapshot.getLong("counter") + 1);
467+
return "bar";
468+
}
469+
});
470+
471+
assertEquals("foo", firstTransaction.get());
472+
assertEquals("bar", secondTransaction.get());
473+
assertEquals(3, attempts.intValue());
474+
assertEquals(3, (long) documentReference.get().get().getLong("counter"));
447475
}
448476

449477
@Test

0 commit comments

Comments
 (0)