2016-11-14 2 views
0

В моем классе обслуживания (который помечается, как транзакционные), я уточняю, а затем сохранить объект как:зимуют получить данные после промывки перед тем совершить

myObj.save(flush:true) //(Thread A, updates the value, Step A) 

После этого, обработка данных занимает место, которое занимает много время. Во время этой обработки в классах доменов внесено множество изменений, но эти изменения здесь не актуальны. Поскольку вся эта обработка выполняется в одном классе услуг, она является частью одной транзакции.

Теперь, в то же время, когда все этой обработка происходят на другой поток, который является частью другого сеанса спящего доступ

MyObj.findAll() //Thread B и в наборе результатов я вижу обновленное значение. Значение, которое было обновлено в Step A Однако поток A еще не завершен, и, тем самым, изменения еще не привязаны к базе данных. Я могу подтвердить это, потому что в то же время, если я запускаю запрос непосредственно в workbench mysql, я не вижу изменений. Изменения видны только при доступе объектов через спящий режим.

Мне показалось, что если изменения сделаны в результате флеша, то эти изменения видны в одной и той же транзакции, а не в других транзакциях. Может кто-то прояснить?

ответ

1

Ответ заключается в том, что это зависит от уровня изоляции, используемого на сервере mysql. Как MySQL документация по innodb transaction isolation levels говорит:

уровень изоляции является установкой, которая точно настраивает баланс между производительностью и надежностью, последовательностью и воспроизводимостями результатов, когда несколько операций внесением изменений и выполнением запросов на в то же время.

InnoDB предлагает все уровни изоляции транзакций четыре описанных в SQL: стандарт 1992: READ UNCOMMITTED ПРОЧТИТЕ COMMITTED, REPEATABLE READ, и SERIALIZABLE. Уровень изоляции по умолчанию для InnoDB - ПОВТОРНЫЙ READ.

В документации подробно описываются различия между различными уровнями. Я хотел бы обратить ваше внимание особенно на считываемых неподтвержденными уровне:

ЗЕЬЕСТ выполняются в nonlocking моде, а возможно более ранняя версия строки может быть использован. Таким образом, используя этот уровень изоляции , такие считывания несовместимы. Это также называется грязным считывателем . В противном случае этот уровень изоляции работает как READ COMMITTED.

Этот уровень изоляции позволяет запрашивать данные, обновляемые другими транзакциями, которые еще не были совершены. Однако, прежде чем использовать этот уровень изоляции в вашем коде, PLS убедитесь, что вы понимаете все последствия этого уровня изоляции. Вы не можете вишнево выбирать, какие транзакционные данные вам не нужны. Таким образом, вы можете подождать немного дольше, чтобы получить зафиксированные данные.

+0

Спасибо за объяснение, это действительно помогает. Однако, когда я проверяю уровень изоляции в MySQL, используя запрос «select @@ GLOBAL.tx_isolation, @@ tx_isolation;» он показывает «REPEATABLE-READ». Я буду исследовать, устанавливает ли hibernate некоторый уровень изоляции, хотя это не должно быть так, но я все равно попытаюсь это выяснить.Любая другая идея/объяснение, почему это может происходить после уровня изоляции, повторяется. – Zohaib

+0

Как вы можете видеть из первой цитаты в ответе: «Уровень изоляции по умолчанию для InnoDB - это REPEATABLE READ». «По моему опыту ORM редко устанавливают уровни изоляции, они просто используют все, что установлено. – Shadow

+0

Да, это то, что я бы тоже предположил. Hibernate определенно не устанавливает уровень изоляции. Вот почему первоначальная первопричина до сих пор не известна. Спасибо за ваше время, сообщите мне, есть ли что-нибудь еще, что я должен исследовать, чтобы найти, почему поток B читает обновление, когда threadA еще не закончен. – Zohaib

Смежные вопросы