diff --git a/.github/workflows/push-docker-image.yaml b/.github/workflows/push-docker-image.yaml index ac53f27b3..fecd0c8fe 100644 --- a/.github/workflows/push-docker-image.yaml +++ b/.github/workflows/push-docker-image.yaml @@ -29,6 +29,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 + - name: Fetch tags + run: | + git fetch --prune --unshallow --tags + - name: Login to Docker Hub id: login-docker-hub uses: docker/login-action@v1 diff --git a/server/services/v1/api.go b/server/services/v1/api.go index b7fd97f88..f7339528e 100644 --- a/server/services/v1/api.go +++ b/server/services/v1/api.go @@ -439,7 +439,11 @@ func (s *apiService) GetInfo(_ context.Context, _ *api.GetInfoRequest) (*api.Get func (s *apiService) Run(ctx context.Context, req *ReqOptions) (*Response, error) { queryLifecycle := s.queryLifecycleFactory.Get() - return queryLifecycle.run(ctx, req) + resp, err := queryLifecycle.run(ctx, req) + if err == kv.ErrConflictingTransaction { + return nil, api.Errorf(codes.Aborted, err.Error()) + } + return resp, err } func (s *apiService) Stream(r *api.StreamRequest, stream api.Tigris_StreamServer) error { diff --git a/server/services/v1/query_lifecycle.go b/server/services/v1/query_lifecycle.go index d1dbbb77d..3d6ba46a2 100644 --- a/server/services/v1/query_lifecycle.go +++ b/server/services/v1/query_lifecycle.go @@ -91,7 +91,7 @@ func (q *queryLifecycle) createOrGetTenant() (*metadata.Tenant, error) { return tenant, nil } -func (q *queryLifecycle) run(ctx context.Context, options *ReqOptions) (*Response, error) { +func (q *queryLifecycle) run(ctx context.Context, options *ReqOptions) (resp *Response, txErr error) { if options == nil { return nil, api.Errorf(codes.Internal, "empty options") } @@ -111,8 +111,6 @@ func (q *queryLifecycle) run(ctx context.Context, options *ReqOptions) (*Respons return nil, err } - var resp *Response - var txErr error defer func() { var err error if txErr == nil { diff --git a/store/kv/errors.go b/store/kv/errors.go index 033981e01..fe3b06967 100644 --- a/store/kv/errors.go +++ b/store/kv/errors.go @@ -5,13 +5,16 @@ import "fmt" type StoreErrCode byte const ( - ErrCodeInvalid StoreErrCode = 0x00 - ErrCodeDuplicateKey StoreErrCode = 0x01 + ErrCodeInvalid StoreErrCode = 0x00 + ErrCodeDuplicateKey StoreErrCode = 0x01 + ErrCodeConflictingTransaction StoreErrCode = 0x02 ) var ( // ErrDuplicateKey is returned when an insert call is made for a key that already exist. ErrDuplicateKey = NewStoreError(ErrCodeDuplicateKey, "duplicate key value, violates key constraint") + // ErrConflictingTransaction is returned when there are conflicting transactions. + ErrConflictingTransaction = NewStoreError(ErrCodeConflictingTransaction, "transaction not committed due to conflict with another transaction") ) type StoreError struct { diff --git a/store/kv/fdb.go b/store/kv/fdb.go index 48716e3a2..fef5c9bfa 100644 --- a/store/kv/fdb.go +++ b/store/kv/fdb.go @@ -474,7 +474,6 @@ func (t *ftx) Commit(ctx context.Context) error { } err = t.tx.Commit().Get() - if err == nil { break } @@ -483,7 +482,11 @@ func (t *ftx) Commit(ctx context.Context) error { var ep fdb.Error if xerrors.As(err, &ep) { - err = t.tx.OnError(ep).Get() + if ep.Code == 1020 { + err = ErrConflictingTransaction + } else if err1 := t.tx.OnError(ep).Get(); err1 != nil { + err = err1 + } } if err != nil {