Operations Required
Set time limits on every query
Give every query and transaction a time limit, so one slow query cannot hold locks and connections forever.
How to do it
In PostgreSQL, set statement_timeout and idle_in_transaction_session_timeout for the app's role, and transaction_timeout from version 17. In MySQL, max_execution_time limits only SELECT statements, in milliseconds. In SQLite, set busy_timeout so a waiting write gives up. Set the driver's timeout too. Give reports and migrations their own longer limits on purpose. Keep the query limit shorter than the request's, as timeouts says.
Example
ALTER ROLE shop_app SET statement_timeout = '5s';
ALTER ROLE shop_app SET idle_in_transaction_session_timeout = '30s';
How to check
Run SELECT pg_sleep(60) in PostgreSQL, or SELECT SLEEP(60) in MySQL, through the app's connection. It is cancelled at the set limit.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers data playbook: https://agentwranglers.se/playbook/data/operations/query-timeouts.