Contesto: il framework utilizzato è Spring e tutte le query vengono eseguite con JdbcTemplate. La versione di Mysql Server è 5.6.19. Il tableè una InnoDB tablee le impostazioni predefinite, come auto commite livello di isolamento ripetibile-lettura è impostato.
Problema : si Insertverifica un errore all'interno di una transazione e un utente selectche legge gli stessi dati inseriti non li vede. Le selectcorse dopo il inserte dopo l' insertoperazione ha commited.
Ho abilitato il registro bin e il registro generale in mysql. Registri pertinenti di seguito
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 query
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, First insert(249935389) non dovrebbe far parte della transazione. È una chiamata API separata e completamente non correlata. Potrebbe essere primavera mescolando con la transazione o sto leggendo il registro sbagliato? AFAIK poiché si trova sullo stesso thread implica che l'inserimento è nella transazione.
I prossimi due insertsfanno parte della transazione e sembra che commetta. (249.936.514). Ora la query di selezione (l'ultima nel registro generale) viene eseguita dopo il commit e non vede i dati. Restituisce 0 righe. Come può succedere considerando i dati committed? O commitnon è sul thread 40? Dal momento che non ha l'id thread.
Per riassumere ho due domande.
Fa il
BEGINnell'essere binlog prima dellaINSERT INTO user_geo_loc(che non fa parte della transazione), è presente un bug con la primavera / JDBC o MySql semplicemente lo fa come sa questa transazione, ha già commesso (come le transazioni vengono scritte binlog quando hanno è riuscito) e quindi non verrà mai eseguito il rollback.Dato che il commit avviene prima della selezione (commit è alle 14:16:06 e select è alle 14:16:07) come mai la selezione non restituisce la riga inserita dalla transazione?
Questo è estremamente sconcertante. Qualsiasi aiuto sarebbe apprezzato
Nota: le query nel cestino e nel registro delle query sono state modificate per rimuovere informazioni riservate. Ma l'essenza delle domande rimane la stessa
Modifica: aggiornato con il registro generale e il registro delle query con un esempio dettagliato.
BEGINo START TRANSACTION. Stai invece usando autocommit=0? (Preferisco iniziare ... commit; chiarisce l'entità della transazione.)