Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go binding: do not commit read-only transactions #11366

Merged
merged 2 commits into from
May 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions bindings/go/src/fdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type DatabaseOptions struct {
}

// Close will close the Database and clean up all resources.
// You have to ensure that you're not resuing this database.
// You have to ensure that you're not reusing this database.
func (d Database) Close() {
// Remove database object from the cached databases
if d.isCached {
Expand Down Expand Up @@ -91,14 +91,25 @@ func (d *database) destroy() {
// automatically creating and committing a transaction with appropriate retry
// behavior.
func (d Database) CreateTransaction() (Transaction, error) {
tr, err := d.createTransaction(true)
if err != nil {
return Transaction{}, err
}

return tr, nil
}

func (d Database) createTransaction(setFinalizer bool) (Transaction, error) {
var outt *C.FDBTransaction

if err := C.fdb_database_create_transaction(d.ptr, &outt); err != 0 {
return Transaction{}, Error{int(err)}
}

t := &transaction{outt, d}
runtime.SetFinalizer(t, (*transaction).destroy)
if setFinalizer {
runtime.SetFinalizer(t, (*transaction).destroy)
}

return Transaction{t}, nil
}
Expand Down Expand Up @@ -209,6 +220,7 @@ func (d Database) Transact(f func(Transaction) (interface{}, error)) (interface{
//
// The transaction is retried if the error is or wraps a retryable Error.
// The error is unwrapped.
// Read transactions are never committed and destroyed before returning to caller.
//
// Do not return Future objects from the function provided to ReadTransact. The
// Transaction created by ReadTransact may be finalized at any point after
Expand All @@ -219,20 +231,19 @@ func (d Database) Transact(f func(Transaction) (interface{}, error)) (interface{
// See the ReadTransactor interface for an example of using ReadTransact with
// Transaction, Snapshot and Database objects.
func (d Database) ReadTransact(f func(ReadTransaction) (interface{}, error)) (interface{}, error) {
tr, e := d.CreateTransaction()
tr, e := d.createTransaction(false)
// Any error here is non-retryable
if e != nil {
return nil, e
}
defer tr.transaction.destroy()

wrapped := func() (ret interface{}, e error) {
defer panicToError(&e)

ret, e = f(tr)

if e == nil {
e = tr.Commit().Get()
}
// read-only transactions are not committed and destroyed automatically on exit

return
}
Expand Down