> For the complete documentation index, see [llms.txt](https://goooqo.docs.doyto.win/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://goooqo.docs.doyto.win/api/transaction.md).

# Transaction

## Definition

After creating the database connection, we use the database connection to create a transaction manager.

Transaction management in GoooQo is accomplished through the cooperation of TransactionManager and TransactionContext (TC for short).

```go
package core

import (
	"context"
	"database/sql/driver"
)

type TransactionManager interface {
	GetClient() any
	StartTransaction(ctx context.Context) (TransactionContext, error)
	SubmitTransaction(ctx context.Context, callback func(tc TransactionContext) error) error
}

type TransactionContext interface {
	context.Context
	driver.Tx
	Parent() context.Context
	SavePoint(name string) error
	RollbackTo(name string) error
}
```

The method `TransactionManager#StartTransaction` is responsible for starting a transaction and returning TC; TC combines `driver.Tx` and is responsible for transaction commit and rollback.

The `TxDataAccess` interface combines `TransactionManager` and `DataAccess`, which can conveniently manage transactions while providing database operations.

```go
type TxDataAccess[E Entity] struct {
	TransactionManager
	DataAccess[E]
}
```

## Usages

Use the database connection `db` to create a TransactionManager `tm`:

<pre class="language-go"><code class="lang-go"><strong>db := rdb.Connect("app.properties")
</strong>defer rdb.Disconnect(db)
tm := rdb.NewTransactionManager(db)
</code></pre>

Use `StartTransaction` to start a transaction and manually commit or rollback the transaction:

```go
tc, err := tm.StartTransaction(ctx)
userQuery := UserQuery{ScoreLt: P(80)}
cnt, err := userDataAccess.DeleteByQuery(tc, userQuery)
if err != nil {
	err = RollbackFor(tc, err)
	return 0
}
err = tc.Commit()
return cnt
```

Or use `SubmitTransaction` to submit the transaction via callback:

```go
err := tm.SubmitTransaction(ctx, func(tc TransactionContext) (err error) {
    // transaction body
    return
})
```
