Skip to content
/ satomic Public

Simple nested SQL transactions/savepoints in Golang

License

Notifications You must be signed in to change notification settings

dhui/satomic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

2fd3222 · Jan 26, 2025

History

68 Commits
Jan 26, 2025
Mar 9, 2023
Jan 24, 2025
Jan 26, 2025
Jan 12, 2019
Mar 9, 2023
Jan 5, 2020
Dec 15, 2018
Jan 24, 2025
Dec 17, 2018
Dec 15, 2018
Jan 11, 2019
Jan 24, 2025
Jan 24, 2025
Jul 30, 2019
Jan 11, 2019
Jan 24, 2025

Repository files navigation

satomic

GitHub Workflow Status (branch) Code Coverage GoDoc Go Report Card GitHub Release Supported Go versions

satomic is a Golang package that makes managing nested SQL transactions/savepoints easier

Overview

Create a Querier and use the Atomic() method. Any SQL statements inside the Atomic() method's callback function will be appropriately wrapped in a transaction or savepoint. Transaction and savepoint management will be handled for you automatically. Any error returned by the callback function (or unrecovered panic) will rollback the savepoint or transaction accordingly. A new Querier instance is also provided to the Atomic() method's callback function to allow nesting savepoints.

Status

satomic is not stable yet, so the interfaces may change in a non-backwards compatible manner. satomic follows Semantic Versioning 2.0.0. While the major version number is 0, all backwards compatible changes will be denoted by a minor version number bump. All other changes will increase the patch version number.

Example usage

package main

import (
    "context"
    "database/sql"
    "github.com/dhui/satomic"
    "github.com/dhui/satomic/savepointers/postgres"
)

// Error handling omitted for brevity. Actual code should handle errors
func main() {
    ctx := context.Background()
    var db *sql.DB  // Use an actual db

    // savepointer should match the db driver used
    q, _ := satomic.NewQuerier(ctx, db, postgres.Savepointer{}, sql.TxOptions{})

    q.Atomic(func(ctx context.Context, q satomic.Querier) error {
        // In transaction
        var dummy int
        q.QueryRowContext(ctx, "SELECT 1;").Scan(&dummy)

        q.Atomic(func(ctx context.Context, q satomic.Querier) error {
            // In first savepoint
            return q.QueryRowContext(ctx, "SELECT 2;").Scan(&dummy)
        })

        q.Atomic(func(ctx context.Context, q satomic.Querier) error {
            // In second savepoint
            q.QueryRowContext(ctx, "SELECT 3;").Scan(&dummy)

            q.Atomic(func(ctx context.Context, q satomic.Querier) error {
                // In third savepoint
                q.QueryRowContext(ctx, "SELECT 4;").Scan(&dummy)
                return nil
            })

            return nil
        })

        return nil
    })
}

A more complete example can be found in the GoDoc

For usage with sqlx, use github.com/dhui/satomic/satomicx

What's with the name?

Go SQL atomic => satomic


Inspired by sqlexp and Django's atomic decorator/context manager.