<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def notify_txn_invalid(self, txn_id, message=None, extended_data=None):
 """Adds a batch id to the invalid cache along with the id of the transaction that was rejected and any error message or extended data. Removes that batch id from the pending set. The cache is only temporary, and the batch info will be purged after one hour. Args: txn_id (str):
 The id of the invalid batch message (str, optional):
 Message explaining why batch is invalid extended_data (bytes, optional):
 Additional error data """

        invalid_txn_info = {'id': txn_id}
        if message is not None:
            invalid_txn_info['message'] = message
        if extended_data is not None:
            invalid_txn_info['extended_data'] = extended_data

        with self._lock:
            for batch_id, txn_ids in self._batch_info.items():
                if txn_id in txn_ids:
                    if batch_id not in self._invalid:
                        self._invalid[batch_id] = [invalid_txn_info]
                    else:
                        self._invalid[batch_id].append(invalid_txn_info)
                    self._pending.discard(batch_id)
                    self._update_observers(batch_id, ClientBatchStatus.INVALID)
                    return