Acho que há um mal-entendido sobre o que constitui uma transação aqui.
Seu exemplo abre uma conexão e executa um transação nele. Você executa várias instruções SQL nessa transação, mas a fecha completamente após a confirmação. Claro que é mais do que bom.
Executando várias transações (em oposição a apenas instruções SQL), fica assim:
conn = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test")
for j in range(10):
try:
for i in range(10):
cur = conn.cursor()
query = "DELETE FROM SomeTable WHERE ID = %d" % i
cur.execute(query)
cur.close()
conn.commit()
except Exception:
conn.rollback()
conn.close()
O código acima confirma 10 transações, cada uma consistindo em 10 instruções de exclusão individuais.
E sim, você deve poder reutilizar a conexão aberta para isso sem problemas, desde que não compartilhe essa conexão entre os threads.
Por exemplo, SQLAlchemy reutiliza conexões agrupando-as, distribuindo conexões abertas conforme necessário para o aplicativo. Novas transações e novas instruções são executadas nessas conexões ao longo do tempo de vida de um aplicativo, sem precisar ser fechado até que o aplicativo seja encerrado.