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 table
e le impostazioni predefinite, come auto commit
e livello di isolamento ripetibile-lettura è impostato.
Problema : si Insert
verifica un errore all'interno di una transazione e un utente select
che legge gli stessi dati inseriti non li vede. Le select
corse dopo il insert
e dopo l' insert
operazione 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 inserts
fanno 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 commit
non è sul thread 40? Dal momento che non ha l'id thread.
Per riassumere ho due domande.
Fa il
BEGIN
nell'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.
BEGIN
o START TRANSACTION
. Stai invece usando autocommit=0
? (Preferisco iniziare ... commit; chiarisce l'entità della transazione.)