Index: impl/memory/context.go |
diff --git a/impl/memory/context.go b/impl/memory/context.go |
index 7a0deec8a36a310962cf670d47d92b517d1b0be9..7fc489d4e27b8fb58ebcd3ca925c75f474dfa263 100644 |
--- a/impl/memory/context.go |
+++ b/impl/memory/context.go |
@@ -11,6 +11,7 @@ import ( |
ds "github.com/luci/gae/service/datastore" |
"github.com/luci/luci-go/common/logging/memlogger" |
+ |
"golang.org/x/net/context" |
) |
@@ -128,7 +129,6 @@ func UseWithAppID(c context.Context, aid string) context.Context { |
memctx := newMemContext(fqAppID) |
c = context.WithValue(c, memContextKey, memctx) |
- c = context.WithValue(c, memContextNoTxnKey, memctx) |
c = useGID(c, func(mod *globalInfoData) { |
mod.appID = aid |
mod.fqAppID = fqAppID |
@@ -136,21 +136,19 @@ func UseWithAppID(c context.Context, aid string) context.Context { |
return useMod(useMail(useUser(useTQ(useRDS(useMC(useGI(c))))))) |
} |
-func cur(c context.Context) (p *memContext) { |
- p, _ = c.Value(memContextKey).(*memContext) |
- return |
-} |
- |
-func curNoTxn(c context.Context) (p *memContext) { |
- p, _ = c.Value(memContextNoTxnKey).(*memContext) |
- return |
+func cur(c context.Context) (*memContext, bool) { |
+ if txn := c.Value(currentTxnKey); txn != nil { |
+ // We are in a Transaction. |
+ return txn.(*memContext), true |
+ } |
+ return c.Value(memContextKey).(*memContext), false |
} |
type memContextKeyType int |
var ( |
- memContextKey memContextKeyType |
- memContextNoTxnKey memContextKeyType = 1 |
+ memContextKey memContextKeyType |
+ currentTxnKey = 1 |
) |
// weird stuff |
@@ -174,7 +172,10 @@ func (d *dsImpl) RunInTransaction(f func(context.Context) error, o *ds.Transacti |
// Keep in separate function for defers. |
loopBody := func(applyForReal bool) error { |
- curMC := cur(d.c) |
+ curMC, inTxn := cur(d) |
+ if inTxn { |
+ return errors.New("datastore: nested transactions are not supported") |
+ } |
txnMC := curMC.mkTxn(o) |
@@ -185,7 +186,7 @@ func (d *dsImpl) RunInTransaction(f func(context.Context) error, o *ds.Transacti |
txnMC.endTxn() |
}() |
- if err := f(context.WithValue(d.c, memContextKey, txnMC)); err != nil { |
+ if err := f(context.WithValue(d, currentTxnKey, txnMC)); err != nil { |
return err |
} |
@@ -193,7 +194,7 @@ func (d *dsImpl) RunInTransaction(f func(context.Context) error, o *ds.Transacti |
defer txnMC.Unlock() |
if applyForReal && curMC.canApplyTxn(txnMC) { |
- curMC.applyTxn(d.c, txnMC) |
+ curMC.applyTxn(d, txnMC) |
} else { |
return ds.ErrConcurrentTransaction |
} |