mirror of https://github.com/etcd-io/bbolt.git
Merge pull request #78 from benbjohnson/tx-managed
Mark Do()/With() transaction as managed.pull/34/head
commit
8303617b72
23
db.go
23
db.go
|
@ -349,19 +349,26 @@ func (db *DB) removeTx(t *Tx) {
|
|||
}
|
||||
}
|
||||
|
||||
// Do executes a function within the context of a read-write transaction.
|
||||
// Do executes a function within the context of a read-write managed transaction.
|
||||
// If no error is returned from the function then the transaction is committed.
|
||||
// If an error is returned then the entire transaction is rolled back.
|
||||
// Any error that is returned from the function or returned from the commit is
|
||||
// returned from the Do() method.
|
||||
//
|
||||
// Attempting to manually commit or rollback within the function will cause a panic.
|
||||
func (db *DB) Do(fn func(*Tx) error) error {
|
||||
t, err := db.RWTx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Mark as a managed tx so that the inner function cannot manually commit.
|
||||
t.managed = true
|
||||
|
||||
// If an error is returned from the function then rollback and return error.
|
||||
if err := fn(t); err != nil {
|
||||
err = fn(t)
|
||||
t.managed = false
|
||||
if err != nil {
|
||||
t.Rollback()
|
||||
return err
|
||||
}
|
||||
|
@ -369,8 +376,10 @@ func (db *DB) Do(fn func(*Tx) error) error {
|
|||
return t.Commit()
|
||||
}
|
||||
|
||||
// With executes a function within the context of a transaction.
|
||||
// With executes a function within the context of a managed transaction.
|
||||
// Any error that is returned from the function is returned from the With() method.
|
||||
//
|
||||
// Attempting to manually rollback within the function will cause a panic.
|
||||
func (db *DB) With(fn func(*Tx) error) error {
|
||||
t, err := db.Tx()
|
||||
if err != nil {
|
||||
|
@ -378,8 +387,14 @@ func (db *DB) With(fn func(*Tx) error) error {
|
|||
}
|
||||
defer t.Rollback()
|
||||
|
||||
// Mark as a managed tx so that the inner function cannot manually rollback.
|
||||
t.managed = true
|
||||
|
||||
// If an error is returned from the function then pass it through.
|
||||
return fn(t)
|
||||
err = fn(t)
|
||||
t.managed = false
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy writes the entire database to a writer.
|
||||
|
|
17
db_test.go
17
db_test.go
|
@ -111,6 +111,23 @@ func TestDBTxBlockWhileClosed(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
// Ensure a panic occurs while trying to commit a managed transaction.
|
||||
func TestDBTxBlockWithManualCommitAndRollback(t *testing.T) {
|
||||
withOpenDB(func(db *DB, path string) {
|
||||
db.Do(func(tx *Tx) error {
|
||||
tx.CreateBucket("widgets")
|
||||
assert.Panics(t, func() { tx.Commit() })
|
||||
assert.Panics(t, func() { tx.Rollback() })
|
||||
return nil
|
||||
})
|
||||
db.With(func(tx *Tx) error {
|
||||
assert.Panics(t, func() { tx.Commit() })
|
||||
assert.Panics(t, func() { tx.Rollback() })
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Ensure that the database can be copied to a file path.
|
||||
func TestDBCopyFile(t *testing.T) {
|
||||
withOpenDB(func(db *DB, path string) {
|
||||
|
|
8
tx.go
8
tx.go
|
@ -18,6 +18,7 @@ type txid uint64
|
|||
// quickly grow.
|
||||
type Tx struct {
|
||||
writable bool
|
||||
managed bool
|
||||
db *DB
|
||||
meta *meta
|
||||
buckets *buckets
|
||||
|
@ -155,7 +156,9 @@ func (t *Tx) DeleteBucket(name string) error {
|
|||
// Commit writes all changes to disk and updates the meta page.
|
||||
// Returns an error if a disk write error occurs.
|
||||
func (t *Tx) Commit() error {
|
||||
if t.db == nil {
|
||||
if t.managed {
|
||||
panic("managed tx commit not allowed")
|
||||
} else if t.db == nil {
|
||||
return nil
|
||||
} else if !t.writable {
|
||||
t.Rollback()
|
||||
|
@ -194,6 +197,9 @@ func (t *Tx) Commit() error {
|
|||
|
||||
// Rollback closes the transaction and ignores all previous updates.
|
||||
func (t *Tx) Rollback() {
|
||||
if t.managed {
|
||||
panic("managed tx rollback not allowed")
|
||||
}
|
||||
t.close()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue