Контекст: используется среда Spring, и все запросы выполняются с помощью JdbcTemplate. Версия Mysql Server - 5.6.19. table
Это InnoDB table
и по умолчанию , как auto commit
и уровень изоляции повторяемое-чтение установлено.
Проблема : Событие Insert
происходит внутри транзакции, и a, select
который читает те же самые вставленные данные, не видит данные. В select
пробегах послеinsert
и после того , как insert
сделка имеет commited
.
Я включил журнал бина, а также общий журнал в MySQL. Соответствующие журналы ниже
бен-журнал:
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/*!*/;
Журнал запросов
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'
Любопытно, что First insert
(249935389) вообще не должен участвовать в транзакции. Это отдельный вызов API и совершенно не связанный. Это может быть весна, смешивающая это с транзакцией, или я читаю журнал неправильно? AFAIK, поскольку он находится в том же потоке, это означает, что вставка находится в транзакции.
Следующие два inserts
являются частью транзакции, и похоже, что она фиксируется. (249936514). Теперь запрос на выборку (последний в общем журнале) выполняется после коммита и не видит данных. Возвращает 0 строк. Как это может произойти, учитывая данные committed
? Или commit
не в теме 40? Так как у него нет идентификатора потока.
Подводя итог, у меня есть два вопроса.
Имеет ли место
BEGIN
в binlog передINSERT INTO user_geo_loc
(который не является частью транзакции), это ошибка в Spring / Jdbc или MySql просто делает это, поскольку он знает, что эта транзакция уже зафиксирована (поскольку транзакции записываются в binlog, когда они удалось) и поэтому никогда не будет откат.Если фиксация происходит до выбора (фиксация в 14:16:06, а выбор в 14:16:07), как получается, что выбор не возвращает строку, вставленную транзакцией?
Это очень сложно. Любая помощь будет оценена
Примечание. Запросы в корзине и журнале запросов были отредактированы для удаления конфиденциальной информации. Но суть запросов остается прежней
Изменить: Обновлен общий журнал и журнал запросов с подробным примером.
BEGIN
или START TRANSACTION
. Вы вместо этого используете autocommit=0
? (Я предпочитаю начинать ... фиксировать; это ясно