La semana pasada me encontré con uno de esos misterios justo trabajando con MySQL, en el laburo. Hace rato que no me pasaba.
Tales misterios, para los que no están acostumbrados, son aquellos en que surge una dificultad técnica, pero disfrazada de acontecimiento que se califica como "no puede ser", "me está haciendo algo raro", "che, esto se rompió", etc., pero que luego resulta ser que uno está haciendo algo mal.
Lo divertido de tales misterios es que lo obligan a uno a leer, releer y analizar documentación, buscar en la web, aprendiendo muchísimo en el proceso.
El problema que tenía era que un colaborador mío estaba usando un módulo que yo tenía para acceder al MySQL desde Python, usando MySQLdb, pero con apenas algo de laburo para hacerla más fácil, y cuando insertaba algo en una tabla, por otro lado no veía lo insertado.
Es decir, el estaba con un programa por un lado, y con la linea de comandos del MySQL por el otro. Y cuando insertaba algo en la base desde el programa, no lo veía por la linea de comandos. Es más, a veces la inserción daba timeout porque la tabla estaba lockeada.
Luego de tres horas de buscar, probar, y reescribir mi módulo de MySQL utilizando la Python DB API 2.0, encontré cual era el problema.
Primero, algo que desconocía. Que cuando estás en una tabla InnoDB, que maneja transacciones, el SELECT también es una transacción, y como tal, luego de la misma, hay que hacer un COMMIT. Y lo otro es que al levantar una conexión con MySQLdb, el autocommit está por default deshabilitado (al contrario que por linea de comandos del MySQL que por default está habilitado).
Habilité entonces en mi módulo el autocommit, para que el SELECT no me bloquee la tabla y que luego me dé el timeout, y listo, :) Todo solucionado.
Costó, pero aprendí bastante más de InnoDB en MySQL, y aproveché para actualizar mi módulo, que la verdad es que era un desastre, después de todo fue mi primer clase hecha en Python!