internal/worker: fix readAfterWrite bug

When triaging GHSAs, make a list of all GHSAs that need to
be created or updated and do the database writes all at once.

We need to do this to avoid a readAfterWrite bug in which
we attempt to read CVE records after writing GHSA records.

Change-Id: Ib5745e19f3eb9460178d02f7a7e3bc6aa024a848
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/432995
Run-TryBot: Tatiana Bradley <tatiana@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
diff --git a/internal/worker/update.go b/internal/worker/update.go
index 1bfbdff..d0fb7fa 100644
--- a/internal/worker/update.go
+++ b/internal/worker/update.go
@@ -484,6 +484,8 @@
 		}
 
 		// Determine what needs to be added and modified.
+		var toAdd []*store.GHSARecord
+		var toUpdate []*store.GHSARecord
 		for _, sa := range sas {
 			old := ghsaIDToRecord[sa.ID]
 			if old == nil {
@@ -493,14 +495,10 @@
 				if err != nil {
 					return err
 				}
-				r := &store.GHSARecord{
+				toAdd = append(toAdd, &store.GHSARecord{
 					GHSA:        sa,
 					TriageState: triageState,
-				}
-				if err := tx.CreateGHSARecord(r); err != nil {
-					return err
-				}
-				numAdded++
+				})
 			} else if !old.GHSA.UpdatedAt.Equal(sa.UpdatedAt) {
 				// Modify record.
 				mod := *old
@@ -514,12 +512,23 @@
 				default:
 					// Don't change the TriageState.
 				}
-				if err := tx.SetGHSARecord(&mod); err != nil {
-					return err
-				}
-				numModified++
+				toUpdate = append(toUpdate, &mod)
 			}
 		}
+
+		for _, r := range toAdd {
+			if err := tx.CreateGHSARecord(r); err != nil {
+				return err
+			}
+			numAdded++
+		}
+		for _, r := range toUpdate {
+			if err := tx.SetGHSARecord(r); err != nil {
+				return err
+			}
+			numModified++
+		}
+
 		return nil
 	})
 	stats.NumAdded = numAdded