### Apache Airflow version

2.6.0

### What happened

When marking an EMR Serverless job as failed, the job continues to run.

### What you think should happen instead

The job should be cancelled. Looking at the [EMR Serverless Operator](https://github.com/apache/airflow/blob/a6be96d92828a86e982b53646a9e2eeca00a5463/airflow/providers/amazon/aws/operators/emr.py#L939), I don't see an `on_kill` method, so assuming we just need to add that. 

I'm not sure how to handle the `EmrServerlessCreateApplicationOperator` operator, though - if the workflow has a corresponding `EmrServerlessDeleteApplicationOperator`, we'd probably want to delete the application if the job is cancelled.

### How to reproduce

- Start an EMR Serverless DAG
- Mark the job as failed in the Airflow UI
- See that the EMR Serverless job continues to run

### Operating System

n/a

### Versions of Apache Airflow Providers

`apache-airflow-providers-amazon==8.0.0`

### Deployment

Amazon (AWS) MWAA

### Deployment details

_No response_

### Anything else

_No response_

### Are you willing to submit PR?

- [X] 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)

)
            if self._job_flow_id:
                EmrLogsLink.persist(
                    context=context,
                    operator=self,
                    region_name=self._emr_hook.conn_region_name,
                    aws_partition=self._emr_hook.conn_partition,
                    job_flow_id=self._job_flow_id,
                    log_uri=get_log_uri(emr_client=self._emr_hook.conn, job_flow_id=self._job_flow_id),
                )
            if self.wait_for_completion:
                self._emr_hook.get_waiter("job_flow_waiting").wait(
                    ClusterId=self._job_flow_id,
                    WaiterConfig=prune_dict(
                        {
                            "Delay": self.waiter_delay,
                            "MaxAttempts": self.waiter_max_attempts,
                        }
                    ),
                )
            return self._job_flow_id
    def on_kill(self) -> None:
        """
        Terminate the EMR cluster (job flow). If TerminationProtected=True on the cluster,
        termination will be unsuccessful.
        """
        if self._job_flow_id:
            self.log.info("Terminating job flow %s", self._job_flow_id)
            self._emr_hook.conn.terminate_job_flows(JobFlowIds=[self._job_flow_id])
class EmrModifyClusterOperator(BaseOperator):