Implementation of InternalPushTxn operation.

 The details of the op are spelled out in detail in the Range.InternalPushTxn comments and in the
api.proto comments. Unittests provides full code test coverage including
all error conditions.

Changed MVCC.ResolveWriteIntent to no longer accept a Commit parameter.
Instead, we use more of the provided Txn parameter's fields to correctly
update the MVCC metadata / versioned value. The missing piece here was
handling the case of the timestamp being pushed forward instead of just
having the underlying transaction committed or aborted. In the case of
pushing the timestamp, the MVCC metadata txn field is not set to nil,
it's just updated. We also will end up removing the versioned value with
the previous timestamp and create a new one with the updated timestamp.

Cleaned up TODO file.
This case is fine. Txn-2 will abort Txn-1 using the args.PusheeTxn, which
is Txn-1's transaction at the time it wrote the intent for "a". If nothing
exists yet at the transaction record, it means that Txn-'s intent
transaction is the most up to date txn record we have. We just use it, as
per the comment.

On Thu, Sep 18, 2014 at 2:03 AM, jiangmingyang <notifications@github.com>
wrote:

> In storage/range.go:
>
> > +		reply.SetGoError(err)
> > +		return
> > +	}
> > +	if ok {
> > +		// Start with the persisted transaction record as final transaction.
> > +		reply.PushTxn = gogoproto.Clone(existTxn).(*proto.Transaction)
> > +		// Upgrade the epoch and timestamp as necessary.
> > +		if reply.PushTxn.Epoch < args.PushTxn.Epoch {
> > +			reply.PushTxn.Epoch = args.PushTxn.Epoch
> > +		}
> > +		if reply.PushTxn.Timestamp.Less(args.PushTxn.Timestamp) {
> > +			reply.PushTxn.Timestamp = args.PushTxn.Timestamp
> > +		}
> > +	} else {
> > +		// The transaction doesn't exist yet on disk; use the supplied version.
> > +		reply.PushTxn = gogoproto.Clone(&args.PushTxn).(*proto.Transaction)
>
> How about:
>
> Txn-1 has a write intent for key 'a'.
> Txn-2 try to write key 'a' as well which cause a conflict.
> Txn-2 try to abort Txn-1 by calling InternalPushTxn.
> When executing InternalPushTxn from Txn-2, the heartbert of Txn-1 didin't
> arrive yet.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/cockroachdb/cockroach/pull/65/files#r17710383>.
>