Chromium Code Reviews| Index: impl/memory/context.go |
| diff --git a/impl/memory/context.go b/impl/memory/context.go |
| index 7a0deec8a36a310962cf670d47d92b517d1b0be9..0845a207e4d18d09930c7f9a8384489932938895 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,24 @@ 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 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 |
| } |
| -func curNoTxn(c context.Context) (p *memContext) { |
| - p, _ = c.Value(memContextNoTxnKey).(*memContext) |
| - return |
| +func inTxn(c context.Context) bool { |
|
dnj
2016/09/01 15:25:39
Ended up not needing this, will delete in next pat
iannucci
2016/09/16 01:01:13
sgtm
dnj
2016/09/16 05:44:42
Done.
|
| + _, inTxn := cur(c) |
| + return inTxn |
| } |
| type memContextKeyType int |
| var ( |
| - memContextKey memContextKeyType |
| - memContextNoTxnKey memContextKeyType = 1 |
| + memContextKey memContextKeyType |
| + currentTxnKey = 1 |
| ) |
| // weird stuff |
| @@ -174,7 +177,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 +191,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 +199,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 |
| } |