container: Use wrapper to ensure commit/abort happens
@@ -139,18 +139,28 @@ 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.
// Only read only (deep) copies of containers may be passed in.
func (db *memDB) Save(c *Container) error {
- txn := db.store.Txn(true)
- defer txn.Commit()
+ return db.withTxn(func(txn *memdb.Txn) error {
return txn.Insert(memdbContainersTable, c)
+ })
}
// Delete removes an item by ID
func (db *memDB) Delete(c *Container) error {
- txn := db.store.Txn(true)
-
+ return db.withTxn(func(txn *memdb.Txn) error {
view := &memdbView{txn: txn}
names := view.getNames(c.ID)
@@ -159,11 +169,10 @@ func (db *memDB) Delete(c *Container) error {
}
if err := txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root)); err != nil {
- txn.Abort()
return err
}
- txn.Commit()
return nil
+ })
}
// ReserveName registers a container ID to a name
@@ -171,15 +180,12 @@ func (db *memDB) Delete(c *Container) error {
// Attempting to reserve a container ID to a name that already exists results in an `ErrNameReserved`
// A name reservation is globally unique
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 {
- txn.Abort()
return err
}
if s != nil {
- txn.Abort()
if s.(nameAssociation).containerID != containerID {
return ErrNameReserved
}
@@ -187,23 +193,21 @@ func (db *memDB) ReserveName(name, containerID string) error {
}
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
// Once released, a name can be reserved again
func (db *memDB) ReleaseName(name string) error {
- txn := db.store.Txn(true)
+ return db.withTxn(func(txn *memdb.Txn) error {
if err := txn.Delete(memdbNamesTable, nameAssociation{name: name}); err != nil {
- txn.Abort()
return err
}
- txn.Commit()
return nil
+ })
}
type memdbView struct {
