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:
parent
6c939c756c
commit
19bf0b3e7d
1 changed files with 58 additions and 21 deletions
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue