Why not the third (and in my experience most common) alternative? Autocommit but if you explicitly start a transaction then automcommit is turned off until that transaction has been committed.
If you have more than one statement, then autocommit is usually wrong, and what you usually want is transaction-per-request. If you have exactly one statement, then autocommit is exactly identical to transaction-per-request.
Also part of the transaction-per-request pattern is that the transaction is started when the first statement is invoked. So there's no overhead for zero-statement requests either.
Also part of the transaction-per-request pattern is that the transaction is started when the first statement is invoked. So there's no overhead for zero-statement requests either.