Ejemplo sencillo (CÓDIGO PSEUDO):
for (int i = 0; i < 100; i++) { START TRANSACTION; SELECT id, name FROM employees WHERE id = i; IF (someFunction(id)) { ROLLBACK; CONTINUE; // GO TO NEXT EXECUTION OF FOR LOOP } UPDATE company SET good = good + 1; COMMIT; }¿Puedo usar en este ejemplo COMMIT (así que tendré dos COMMIT en mi script) en lugar de ROLLBACK?
¿Hace alguna diferencia en la base de datos si uso COMMIT en lugar de ROLLBACK después de seleccionar?
¿Hay alguna diferencia entre MySQL y PostgreSQL aquí?
Select por sí mismo no requiere revertir ni confirmar. Esos son necesarios solo después de DML (insertar, actualizar, eliminar). Además, normalmente se considera mejor tener solo 1 compromiso en una transacción. La idea es que toda la transacción tenga éxito por completo o completamente como una unidad. por lo que su pseudocódigo se convierte en:
START TRANSACTION; for (int i = 0; i < 100; i++) { SELECT id, name FROM employees WHERE id = i; IF NOT (someFunction(id)) { UPDATE company SET good = good + 1; } } COMMIT;Entonces, entiendo que su pregunta es si ROLLBACK o COMMIT es mejor cuando, después de solo una selección, determina que no se realizarán cambios en esta transacción.
En lo que respecta a mysql, no hay razón para hacer rollback o commit; dado que no se han realizado cambios, tampoco hace nada, y hacer ninguno no causa problemas. Pero no está claro qué espera lograr al tener la selección dentro de la transacción en primer lugar, o al tener una transacción separada para cada iteración del bucle. Si proporcionara más información, recibiría mejores consejos.
Aquí hay una variación de la respuesta de @Belayer, en la que hice los siguientes cambios:
SELECT , con la intención de reducir el número de consultascompany.good debe incrementarse, antes de incrementarlo finalmente con una sola UPDATE . new_good = 0; SELECT id, name FROM employees WHERE id >= 0 AND i < 100 for each fetched row { IF NOT (someFunction(id)) { new_good++; } } START TRANSACTION /* Probably not needed */ UPDATE company SET good = good + new_good; COMMIT /* Probably not needed */; Esto probablemente elimina por completo la necesidad de una transacción, ya que cualquier llamada fallida a SELECT o fetch no producirá ningún cambio en new_good , por lo que cuando finalmente llegue a UPDATE , new_good seguirá conteniendo un valor válido (incluso si es 0).