func (t *Txn) Put(k, v []byte) error {
	return t.db.put(t, k, v)
}
Put writes a value into the database.
package skeleton
import (
	"sync/atomic"
	"time"
	"github.com/pkg/errors"
)
var (
	ErrTxnConflict = errors.New("an error occurred while committing the transaction")
)
type TransactionStatus int64
const (
	StatusUnknown TransactionStatus = iota
	StatusPending
	StatusAborted
	StatusCommitted
)
type Txn struct {
	db     *DB
	time   time.Time
	status TransactionStatus
}
func (db *DB) NewTxn() *Txn {
	return &Txn{
		db:     db,
		time:   time.Now(),
		status: StatusPending,
	}
}
func (db *DB) Txn(f func(*Txn) error) error {
	for {
		t := db.NewTxn()
		if err := f(t); err != nil {
			return err
		}
		if err := t.Commit(); err != ErrTxnConflict {
			return err
		}
	}
}
func (t *Txn) finish(status TransactionStatus) error {
	if !atomic.CompareAndSwapInt64((*int64)(&t.status), int64(StatusPending), int64(status)) {
		return ErrTxnConflict
	}
	return nil
}
func (t *Txn) Commit() error {
	return t.finish(StatusCommitted)
}
func (t *Txn) Close() error {
	return t.finish(StatusAborted)
}
func (t Txn) Status() TransactionStatus {
	return t.status
}