Would limiting the number of operations in a transaction prevent SQL injection?
It could help avoiding some attacks. However, allowing the adversary to inject a part of the SQL WHERE clause is already quite dangerous.

E.g. injection can change this

SELECT * WHERE name="username"


into

SELECT * WHERE name="Bah!" or true or "too easy!"="x"


The sane thing would be to avoid injection completely. Ideally, in a typed language, the type of a SQL query should NOT be a string, so to prevent concatenation with user data. It should be a query template, to be filled with a special function. Something like

query = new Query(...);
fill(query, { "username": username })


Type systems excel for imposing these constraints of the programs. On the other hand, their use require some thoughtful library design. Sometimes it feels simpler to provide a more low-level solution (like using strings for everything), which is also simpler to use, and possibly document the potential security issues "programmers: don't do this", which can then be ignored by busy programmers, which would often take the shortest path to their goals. Types here would simply block the quick path, forcing the programmers to separate the "query template" part from the "user data" part.

Some languages still use strings for templates, but at least encourage programmers to avoid concatenation, and favor some fill-like function.

fill("SELECT * WHERE name=@username", { "username": username })


The above is doable even in an untyped language.

Moral: let the library perform all the string-escaping for you. The library always checks for special characters, and handles them correctly. You likely won't cover all the tricky cases.

Don't try to patch against an attack by imposing restrictions on just that attack. Consider all the variants for that attack which can pass the restriction. If injection is the problem, prevent injection at the root.