code: func putMulti(c context.Context,
  	keys []*datastore.Key, vals interface{}) ([]*datastore.Key, error) {
  
  	lockMemcacheKeys := make([]string, 0, len(keys))
  	lockMemcacheItems := make([]*memcache.Item, 0, len(keys))
  	for _, key := range keys {
  		if !key.Incomplete() {
  			item := &memcache.Item{
  				Key:        createMemcacheKey(key),
  				Flags:      lockItem,
  				Value:      itemLock(),
  				Expiration: memcacheLockTime,
  			}
  			lockMemcacheItems = append(lockMemcacheItems, item)
  			lockMemcacheKeys = append(lockMemcacheKeys, item.Key)
  		}
  	}
  
  	memcacheCtx, err := memcacheContext(c)
  	if err != nil {
  		return nil, err
  	}
  
  	defer func() {
  		if _, ok := transactionFromContext(c); !ok {
  			// Remove the locks.
  			if err := memcacheDeleteMulti(memcacheCtx,
  				lockMemcacheKeys); err != nil {
  				log.Warningf(c, "putMulti memcache.DeleteMulti %s", err)
  			}
  		}
  	}()
  
  	if tx, ok := transactionFromContext(c); ok {
  		tx.Lock()
  		tx.lockMemcacheItems = append(tx.lockMemcacheItems,
  			lockMemcacheItems...)
  		tx.Unlock()
  	} else if err := memcacheSetMulti(memcacheCtx,
  		lockMemcacheItems); err != nil {
  		return nil, err
  	}
  
  	// Save to the datastore.
  	return datastorePutMulti(c, keys, vals)
  }
docs: // putMulti puts the entities into the datastore and then its local cache.