// InternalHeartbeatTxn updates the transaction status and heartbeat // timestamp after receiving transaction heartbeat messages from // coordinator. Returns the updated transaction. func (r *Range) InternalHeartbeatTxn(batch engine.Engine, ms *engine.MVCCStats, args *proto.InternalHeartbeatTxnRequest, reply *proto.InternalHeartbeatTxnResponse) { key := keys.TransactionKey(args.Txn.Key, args.Txn.ID) var txn proto.Transaction ok, err := engine.MVCCGetProto(batch, key, proto.ZeroTimestamp, true, nil, &txn) if err != nil { reply.SetGoError(err) return } // If no existing transaction record was found, initialize // to the transaction in the request header. if !ok { gogoproto.Merge(&txn, args.Txn) } if txn.Status == proto.PENDING { if txn.LastHeartbeat == nil { txn.LastHeartbeat = &proto.Timestamp{} } if txn.LastHeartbeat.Less(args.Header().Timestamp) { *txn.LastHeartbeat = args.Header().Timestamp } if err := engine.MVCCPutProto(batch, ms, key, proto.ZeroTimestamp, nil, &txn); err != nil { reply.SetGoError(err) return } } reply.Txn = &txn }
// InternalHeartbeatTxn updates the transaction status and heartbeat // timestamp after receiving transaction heartbeat messages from // coordinator. Returns the udpated transaction. func (r *Range) InternalHeartbeatTxn(args *proto.InternalHeartbeatTxnRequest, reply *proto.InternalHeartbeatTxnResponse) { // Create the actual key to the system-local transaction table. key := engine.MakeKey(engine.KeyLocalTransactionPrefix, args.Key) var txn proto.Transaction ok, err := engine.GetProto(r.engine, key, &txn) if err != nil { reply.SetGoError(err) return } // If no existing transaction record was found, initialize // to the transaction in the request header. if !ok { gogoproto.Merge(&txn, args.Txn) } if txn.Status == proto.PENDING { if txn.LastHeartbeat == nil { txn.LastHeartbeat = &proto.Timestamp{} } if txn.LastHeartbeat.Less(args.Header().Timestamp) { *txn.LastHeartbeat = args.Header().Timestamp } if err := engine.PutProto(r.engine, key, &txn); err != nil { reply.SetGoError(err) return } } reply.Txn = &txn }
// InternalHeartbeatTxn updates the transaction status and heartbeat // timestamp after receiving transaction heartbeat messages from // coordinator. Returns the updated transaction. func (r *Range) InternalHeartbeatTxn(batch engine.Engine, ms *engine.MVCCStats, args proto.InternalHeartbeatTxnRequest) (proto.InternalHeartbeatTxnResponse, error) { var reply proto.InternalHeartbeatTxnResponse key := keys.TransactionKey(args.Txn.Key, args.Txn.ID) var txn proto.Transaction if ok, err := engine.MVCCGetProto(batch, key, proto.ZeroTimestamp, true, nil, &txn); err != nil { return reply, err } else if !ok { // If no existing transaction record was found, initialize to a // shallow copy of the transaction in the request header. We copy // to avoid mutating the original below. txn = *args.Txn } if txn.Status == proto.PENDING { if txn.LastHeartbeat == nil { txn.LastHeartbeat = &proto.Timestamp{} } if txn.LastHeartbeat.Less(args.Header().Timestamp) { *txn.LastHeartbeat = args.Header().Timestamp } if err := engine.MVCCPutProto(batch, ms, key, proto.ZeroTimestamp, nil, &txn); err != nil { return reply, err } } reply.Txn = &txn return reply, nil }
// InternalHeartbeatTxn updates the transaction status and heartbeat // timestamp after receiving transaction heartbeat messages from // coordinator. The range will return the current status for this // transaction to the coordinator. func (r *Range) InternalHeartbeatTxn(args *proto.InternalHeartbeatTxnRequest, reply *proto.InternalHeartbeatTxnResponse) { // Create the actual key to the system-local transaction table. key := engine.MakeKey(engine.KeyLocalTransactionPrefix, args.Key) var txn proto.Transaction if _, err := engine.GetProto(r.engine, key, &txn); err != nil { reply.SetGoError(err) return } if txn.Status == proto.PENDING { if !args.Header().Timestamp.Less(txn.LastHeartbeat) { txn.LastHeartbeat = args.Header().Timestamp } if err := engine.PutProto(r.engine, key, &txn); err != nil { reply.SetGoError(err) return } } reply.Status = txn.Status }