Básicamente, una transacción es una secuencia de trabajo realizado de forma ordenada y separada en una BD. Normalmente representan cualquier cambio en la base de datos. Dentro de una transacción ejecutaremos todas las instrucciones o no ejecutaremos ninguna.
En caso de que todas las instrucciones hayan sido ejecutadas de forma exitosa, entonces los cambios serán guardados por lo que haremos commit
de la transacción y así concluiremos que la transacción ha sido exitosa.
Si no son ejecutadas las instrucciones, es decir que alguna de ellas falló, entonces haremos rollback
, es decir, dar marcha atrás en todos los posibles cambios que se generaron en las BD. Lo anterior indica que la transacción ha fallado.
Para ejemplificar lo anterior escribamos primero el código para realizar una inserción:
try:
cursor = conexion.cursor()
query = 'INSERT INTO curso_python VALUES(%s, %s, %s, %s)'
values = ('Eugenia', 'López', 20, 'CDMX')
cursor.execute(query, values)
print("Inserción exitosa")
except Exception as e:
print(f'Ocurrio un error: {e}')
Ahora, por default tenemos que conexion.autocommit=False
lo que quiere decir que no guardamos cambio de manera automática. De hecho, conexion.autocommit=True
que hace que los cambios se guarden de manera automática no es una buena práctica. Ahora bien, puede decirse que la sentencia almacenada en query
representa un cambio en la BD, así, para crear una transacción debemos de aplicar un commit
para el caso enq ue dicha sentencia se ha ejecutado exitosamente, y un rollback
en el caso en que ésta no se haya ejecutado exitosamente. Para ello agregamos
try:
cursor = conexion.cursor()
query = 'INSERT INTO curso_python VALUES(%s, %s, %s, %s)'
values = ('Eugenia', 'López', 20, 'CDMX')
cursor.execute(query, values)
# guardamos los cambios
conexion.commit()
print("Inserción exitosa")
except Exception as e:
# hacemos un rollback
conexion.rollback()
print(f'Ocurrio un error: {e}')
finally:
conexion.close()
El código anterior representa una transacción. Podríamos agregar más sentencias a la transacción
try:
cursor = conexion.cursor()
query = 'INSERT INTO curso_python VALUES(%s, %s, %s, %s)'
values = ('Eugenia', 'López', 20, 'CDMX')
cursor.execute(query, values)
query = 'UPDATE curso_python SET nombre = %s WHERE id_curso=3'
values = ('Denis',)
cursor.execute(query, values)
# guardamos los cambios
conexion.commit()
print("Transacción exitosa")
except Exception as e:
# hacemos un rollback
conexion.rollback()
print(f'Ocurrio un error: {e}')
finally:
conexion.close()
No obstante, utilizar administradores de contexto como lo hicimos en las clases pasadas es lo más adecuado y recomendable para trabajar con las transacciones pues, de manera automática, el administrador de contexto se encarga de realizar el commit
cuando las instrucciones se han ejecutado exitosamente; si éstas no se ejecutaron, de manera automática se hará el rollback
.
Por ende, el código final quedaría como
try:
with conexion:
with conexion.cursor() as cursor:
cursor = conexion.cursor()
query = 'INSERT INTO curso_python VALUES(%s, %s, %s, %s)'
values = ('Eugenia', 'López', 20, 'CDMX')
cursor.execute(query, values)
query = 'UPDATE curso_python SET nombre = %s WHERE id_curso=3'
values = ('Denis',)
cursor.execute(query, values)
print("Transacción exitosa")
except Exception as e:
print(f'Ocurrio un error: {e}')
finally:
conexion.close()
donde quitamos del código conexion.commit()
y conexion.rollback
pues sus funciones son realizadas de forma automática por los administradores de contexto.