code: def _try_free_lease(self, shard_state, slice_retry=False):
      
      @db.transactional
      def _tx():
        fresh_state = model.ShardState.get_by_shard_id(shard_state.shard_id)
        if fresh_state and fresh_state.active:
          # Free lease.
          fresh_state.slice_start_time = None
          fresh_state.slice_request_id = None
          if slice_retry:
            fresh_state.slice_retries += 1
          fresh_state.put()
      try:
        _tx()
      # pylint: disable=broad-except
      except Exception, e:
        logging.warning(e)
        logging.warning(
            "Release lock for shard %s failed. Wait for lease to expire.",
            shard_state.shard_id)
docs: Try to free lease.
  
      A lightweight transaction to update shard_state and unset
      slice_start_time to allow the next retry to happen without blocking.
      We don't care if this fails or not because the lease will expire
      anyway.
  
      Under normal execution, _save_state_and_schedule_next is the exit point.
      It updates/saves shard state and schedules the next slice or returns.
      Other exit points are:
      1. _are_states_consistent: at the beginning of handle, checks
        if datastore states and the task are in sync.
        If not, raise or return.
      2. _attempt_slice_retry: may raise exception to taskqueue.
      3. _save_state_and_schedule_next: may raise exception when taskqueue/db
         unreachable.
  
      This handler should try to free the lease on every exceptional exit point.
  
      Args:
        shard_state: model.ShardState.
        slice_retry: whether to count this as a failed slice execution.