### Description

Add listeners for Datasets (events)

### Use case/motivation

As Airflow administrators, we would like to trigger some external processes based on all datasets being created/updated by our users. We came across the listeners for the dag runs and task instances (which are also useful), but are still missing listeners for datasets.

### Related issues

_No response_

### Are you willing to submit a PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

isouter=True,
            )
            .join(DatasetModel, DatasetModel.id == DagScheduleDatasetReference.dataset_id)
            .group_by(DagScheduleDatasetReference.dag_id)
            .where(DagScheduleDatasetReference.dag_id.in_(dag_ids))
        ).all()
    }
class _StopDagTest(Exception):
    """
    Raise when DAG.test should stop immediately.
    :meta private:
    """
@functools.total_ordering
class DAG(LoggingMixin):
    """
    A dag (directed acyclic graph) is a collection of tasks with directional dependencies.
    A dag also has a schedule, a start date and an end date (optional).  For each schedule,
    (say daily or hourly), the DAG needs to run each individual tasks as their dependencies
    are met. Certain tasks have the property of depending on their own past, meaning that
    they can't run until their previous schedule (and upstream tasks) are completed.
    DAGs essentially act as namespaces for tasks. A task_id can only be
    added once to a DAG.
    Note that if you plan to use time zones all the dates provided should be pendulum
    dates. See :ref:`timezone_aware_dags`.
    .. versionadded:: 2.4
        The *schedule* argument to specify either time-based scheduling logic
        (timetable), or dataset-driven triggers.
    .. deprecated:: 2.4
        The arguments *schedule_interval* and *timetable*. Their functionalities
        are merged into the new *schedule* argument.