Don’t ignore errors from the data layer

If the data layer encountered an error when committing a transaction, then the error was ignored. Now all errors from the data layer which occur when cancelling or committing a transaction are passed to the end-user and displayed accordingly.
This commit is contained in:
Tobie Morgan Hitchcock 2018-01-10 11:33:26 +00:00
parent 6c939c756c
commit 19bf0b3e7d

View file

@ -144,13 +144,21 @@ func (e *executor) execute(ctx context.Context, ast *sql.Query) {
continue continue
case *sql.CancelStatement: case *sql.CancelStatement:
err, buf = e.cancel(buf, err, e.send) err, buf = e.cancel(buf, err, e.send)
if err != nil {
clear()
} else {
clear()
}
trc.Finish() trc.Finish()
clear()
continue continue
case *sql.CommitStatement: case *sql.CommitStatement:
err, buf = e.commit(buf, err, e.send) err, buf = e.commit(buf, err, e.send)
if err != nil {
clear()
} else {
flush()
}
trc.Finish() trc.Finish()
flush()
continue continue
} }
@ -339,9 +347,9 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
} }
// If this is a local transaction for only the // If the context is already closed or errord,
// current statement, then commit or cancel // then ignore this result, clear all queued
// depending on the result error. // changes, and reset the transaction.
select { select {
@ -353,15 +361,44 @@ func (e *executor) operate(ctx context.Context, stm sql.Statement) (res []interf
default: default:
// If this is a local transaction for only the
// current statement, then commit or cancel
// depending on the result error.
if loc && e.dbo.Closed() == false { if loc && e.dbo.Closed() == false {
if !trw || err != nil {
// As this is a local transaction then
// make sure we reset the transaction
// context.
defer e.dbo.Reset()
// If there was an error with the query
// then clear the queued changes and
// return immediately.
if err != nil {
e.dbo.Cancel() e.dbo.Cancel()
e.dbo.Reset()
clear() clear()
return
}
// Otherwise check if this is a read or
// a write transaction, and attempt to
// Cancel or Commit, returning any errors.
if !trw {
if err = e.dbo.Cancel(); err != nil {
clear()
} else {
clear()
}
} else { } else {
e.dbo.Commit() if err = e.dbo.Commit(); err != nil {
e.dbo.Reset() clear()
flush() } else {
flush()
}
} }
} }
@ -380,18 +417,18 @@ func (e *executor) begin(rw bool) (err error) {
func (e *executor) cancel(buf []*Response, err error, chn chan<- *Response) (error, []*Response) { func (e *executor) cancel(buf []*Response, err error, chn chan<- *Response) (error, []*Response) {
defer func() { defer e.dbo.Reset()
e.dbo.Reset()
}()
if e.dbo.TX == nil { if e.dbo.TX == nil {
return nil, buf return nil, buf
} }
e.dbo.Cancel() err = e.dbo.Cancel()
for _, v := range buf { for _, v := range buf {
v.Status = "ERR" v.Status = "ERR"
v.Result = []interface{}{}
v.Detail = "Transaction cancelled"
chn <- v chn <- v
} }
@ -400,29 +437,29 @@ func (e *executor) cancel(buf []*Response, err error, chn chan<- *Response) (err
buf = buf[:len(buf)-1] buf = buf[:len(buf)-1]
} }
return nil, buf return err, buf
} }
func (e *executor) commit(buf []*Response, err error, chn chan<- *Response) (error, []*Response) { func (e *executor) commit(buf []*Response, err error, chn chan<- *Response) (error, []*Response) {
defer func() { defer e.dbo.Reset()
e.dbo.Reset()
}()
if e.dbo.TX == nil { if e.dbo.TX == nil {
return nil, buf return nil, buf
} }
if err != nil { if err != nil {
e.dbo.Cancel() err = e.dbo.Cancel()
} else { } else {
e.dbo.Commit() err = e.dbo.Commit()
} }
for _, v := range buf { for _, v := range buf {
if err != nil { if err != nil {
v.Status = "ERR" v.Status = "ERR"
v.Result = []interface{}{}
v.Detail = "Transaction failed: " + err.Error()
} }
chn <- v chn <- v
} }
@ -432,7 +469,7 @@ func (e *executor) commit(buf []*Response, err error, chn chan<- *Response) (err
buf = buf[:len(buf)-1] buf = buf[:len(buf)-1]
} }
return nil, buf return err, buf
} }