Contexto: el marco utilizado es Spring y todas las consultas se ejecutan con JdbcTemplate. La versión del servidor Mysql es 5.6.19. El valor table
es un valor InnoDB table
predeterminado auto commit
y se establece una lectura repetible de nivel de aislamiento.
Problema : Insert
sucede dentro de una transacción y el select
que lee los mismos datos insertados no ve los datos. Las select
carreras después de la insert
y después de la insert
transacción tiene commited
.
He habilitado bin log así como también log general en mysql. Registros relevantes a continuación
bin-log:
SET TIMESTAMP=1438265764/*!*/;
BEGIN
/*!*/;
# at 249935389
#150730 14:16:04 server id 1 end_log_pos 249935606 CRC32 0xa6aca292 Query thread_id=40 exec_time=0 error_code=0
SET TIMESTAMP=1438265764/*!*/;
insert into user_geo_loc_latest(user_id, lat, lng) values(x,y,z) on duplicate key update lat=y, lng=z
/*!*/;
# at 249935606
#150730 14:16:06 server id 1 end_log_pos 249936255 CRC32 0x2a52c734 Query thread_id=40 exec_time=0 error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table(txnid) VALUES ('885851438265675046')
/*!*/;
# at 249936255
#150730 14:16:06 server id 1 end_log_pos 249936514 CRC32 0x6cd85eb5 Query thread_id=40 exec_time=0 error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table2(x) VALUES (y)
/*!*/;
# at 249936514
#150730 14:16:06 server id 1 end_log_pos 249936545 CRC32 0xceb9ec56 Xid = 9406873
COMMIT/*!*/;
Registro de consultas
150730 14:16:04 40 Query ...
....
40 Query select count(*) from table where txnid = '885851438265675046'
40 Query select @@session.tx_read_only
40 Query INSERT INTO table(txnid) VALUES ('885851438265675046')
40 Query select @@session.tx_read_only
40 Query INSERT INTO table2(x) values(y)
40 Query commit
....
150730 14:16:07 36 Query select pp.*, b.create_date from table pp left join bill b on pp.bill_id = b.bill_id where pp.txnid = '885851438265675046'
Curiosamente, Primero insert
(249935389) no debería ser parte de la transacción en absoluto. Es una llamada API separada y completamente no relacionada. ¿Podría ser primavera mezclarlo con la transacción o estoy leyendo mal el registro? AFAIK ya que está en el mismo hilo, implica que el inserto está en la transacción.
Los siguientes dos inserts
son parte de la transacción y parece que se compromete. (249936514). Ahora la consulta de selección (la última en el registro general) se ejecuta después de la confirmación y no ve los datos. Devuelve 0 filas. ¿Cómo puede suceder esto teniendo en cuenta los datos committed
? ¿O commit
no está en el hilo 40? Ya que no tiene el id del hilo.
Para resumir, tengo dos preguntas.
¿
BEGIN
Está en el binlog estar antes delINSERT INTO user_geo_loc
(que no es parte de la transacción), es un error con spring / Jdbc o MySql simplemente hace esto ya que sabe que esta transacción ya se ha comprometido (ya que las transacciones se escriben en binlog cuando han tuvo éxito) y, por lo tanto, nunca se revierteDado que la confirmación ocurre antes de la selección (la confirmación es a las 14:16:06 y la selección es a las 14:16:07) ¿cómo es que la selección no devuelve la fila insertada por la transacción?
Esto es extremadamente desconcertante. Cualquier ayuda sería apreciada
Nota: Las consultas tanto en el bin como en el registro de consultas se han editado para eliminar información confidencial. Pero la esencia de las consultas sigue siendo la misma.
Editar: actualizado con registro general y registro de consultas con un ejemplo detallado.
BEGIN
o START TRANSACTION
. ¿Estás, en cambio, usando autocommit=0
? (Prefiero comenzar ... comprometer; aclara el alcance de la transacción.)