Selaa lähdekoodia

container: Use wrapper to ensure commit/abort happens

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Aaron Lehmann 8 vuotta sitten
vanhempi
commit
0e57eb95c5
1 muutettua tiedostoa jossa 45 lisäystä ja 41 poistoa
  1. 45 41
      container/view.go

+ 45 - 41
container/view.go

@@ -139,31 +139,40 @@ func (db *memDB) Snapshot() View {
 	}
 	}
 }
 }
 
 
+func (db *memDB) withTxn(cb func(*memdb.Txn) error) error {
+	txn := db.store.Txn(true)
+	err := cb(txn)
+	if err != nil {
+		txn.Abort()
+		return err
+	}
+	txn.Commit()
+	return nil
+}
+
 // Save atomically updates the in-memory store state for a Container.
 // Save atomically updates the in-memory store state for a Container.
 // Only read only (deep) copies of containers may be passed in.
 // Only read only (deep) copies of containers may be passed in.
 func (db *memDB) Save(c *Container) error {
 func (db *memDB) Save(c *Container) error {
-	txn := db.store.Txn(true)
-	defer txn.Commit()
-	return txn.Insert(memdbContainersTable, c)
+	return db.withTxn(func(txn *memdb.Txn) error {
+		return txn.Insert(memdbContainersTable, c)
+	})
 }
 }
 
 
 // Delete removes an item by ID
 // Delete removes an item by ID
 func (db *memDB) Delete(c *Container) error {
 func (db *memDB) Delete(c *Container) error {
-	txn := db.store.Txn(true)
-
-	view := &memdbView{txn: txn}
-	names := view.getNames(c.ID)
+	return db.withTxn(func(txn *memdb.Txn) error {
+		view := &memdbView{txn: txn}
+		names := view.getNames(c.ID)
 
 
-	for _, name := range names {
-		txn.Delete(memdbNamesTable, nameAssociation{name: name})
-	}
+		for _, name := range names {
+			txn.Delete(memdbNamesTable, nameAssociation{name: name})
+		}
 
 
-	if err := txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root)); err != nil {
-		txn.Abort()
-		return err
-	}
-	txn.Commit()
-	return nil
+		if err := txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root)); err != nil {
+			return err
+		}
+		return nil
+	})
 }
 }
 
 
 // ReserveName registers a container ID to a name
 // ReserveName registers a container ID to a name
@@ -171,39 +180,34 @@ func (db *memDB) Delete(c *Container) error {
 // Attempting to reserve a container ID to a name that already exists results in an `ErrNameReserved`
 // Attempting to reserve a container ID to a name that already exists results in an `ErrNameReserved`
 // A name reservation is globally unique
 // A name reservation is globally unique
 func (db *memDB) ReserveName(name, containerID string) error {
 func (db *memDB) ReserveName(name, containerID string) error {
-	txn := db.store.Txn(true)
+	return db.withTxn(func(txn *memdb.Txn) error {
+		s, err := txn.First(memdbNamesTable, memdbIDIndex, name)
+		if err != nil {
+			return err
+		}
+		if s != nil {
+			if s.(nameAssociation).containerID != containerID {
+				return ErrNameReserved
+			}
+			return nil
+		}
 
 
-	s, err := txn.First(memdbNamesTable, memdbIDIndex, name)
-	if err != nil {
-		txn.Abort()
-		return err
-	}
-	if s != nil {
-		txn.Abort()
-		if s.(nameAssociation).containerID != containerID {
-			return ErrNameReserved
+		if err := txn.Insert(memdbNamesTable, nameAssociation{name: name, containerID: containerID}); err != nil {
+			return err
 		}
 		}
 		return nil
 		return nil
-	}
-
-	if err := txn.Insert(memdbNamesTable, nameAssociation{name: name, containerID: containerID}); err != nil {
-		txn.Abort()
-		return err
-	}
-	txn.Commit()
-	return nil
+	})
 }
 }
 
 
 // ReleaseName releases the reserved name
 // ReleaseName releases the reserved name
 // Once released, a name can be reserved again
 // Once released, a name can be reserved again
 func (db *memDB) ReleaseName(name string) error {
 func (db *memDB) ReleaseName(name string) error {
-	txn := db.store.Txn(true)
-	if err := txn.Delete(memdbNamesTable, nameAssociation{name: name}); err != nil {
-		txn.Abort()
-		return err
-	}
-	txn.Commit()
-	return nil
+	return db.withTxn(func(txn *memdb.Txn) error {
+		if err := txn.Delete(memdbNamesTable, nameAssociation{name: name}); err != nil {
+			return err
+		}
+		return nil
+	})
 }
 }
 
 
 type memdbView struct {
 type memdbView struct {