spanner: Fixed session leakage for ApplyAtLeastOnce
Previously session handles where leaked whenever Commit() returned a
non-abort, non-session-not-found error, due to a missing recycle() call.
Fixes #1776.
Change-Id: I45839d3258f96bf6d1dfc15c35e6e146117d70f1
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/51890
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Shanika Kuruppu <skuruppu@google.com>
Reviewed-by: Knut Olav Løite <koloite@gmail.com>
diff --git a/spanner/session.go b/spanner/session.go
index 9a3dfae..301135c 100644
--- a/spanner/session.go
+++ b/spanner/session.go
@@ -130,6 +130,11 @@
func (sh *sessionHandle) destroy() {
sh.mu.Lock()
s := sh.session
+ if s == nil {
+ // sessionHandle has already been recycled.
+ sh.mu.Unlock()
+ return
+ }
tracked := sh.trackedSessionHandle
sh.session = nil
sh.trackedSessionHandle = nil
@@ -137,10 +142,6 @@
sh.stack = nil
sh.mu.Unlock()
- if s == nil {
- // sessionHandle has already been destroyed..
- return
- }
if tracked != nil {
p := s.pool
p.mu.Lock()
diff --git a/spanner/transaction.go b/spanner/transaction.go
index b02a220..a42916b 100644
--- a/spanner/transaction.go
+++ b/spanner/transaction.go
@@ -1018,6 +1018,7 @@
// creations/retrivals.
return ts, err
}
+ defer sh.recycle()
}
res, err := sh.getClient().Commit(contextWithOutgoingMetadata(ctx, sh.getMetadata()), &sppb.CommitRequest{
Session: sh.getID(),
@@ -1043,9 +1044,6 @@
break
}
}
- if sh != nil {
- sh.recycle()
- }
return ts, toSpannerError(err)
}