Для чего происходит блокировка рда в чтении
Блокировки по чтению/записи
Блокировки по чтению/записи (reader/writer locks) (или более точное название «блокировки на множественное чтение и однократную запись») используются в тех случаях, когда доступ к структуре данных должен определяться по следующей схеме: чтение данных выполняет множество потоков, запись — не более одного потока.
Блокировка по чтению/записи (pthread_rwlock_rdlock()) предоставляет доступ по чтению всем потокам, которые его запрашивают. Однако если поток запрашивает блокировку по записи (pthread_rwlock_wrlock()), запрос отклоняется до тех пор, пока все потоки, выполняющие чтение, не снимут свои блокировки по чтению (pthread_rwlock_unlock()).
Множество потоков, выполняющих запись, выстраиваются в очередь (в порядке своих приоритетов), ожидая возможности выполнить операцию записи в защищенную структуру данных. Все блокированные потоки, выполняющие запись, запускаются до того, как читающие потоки снова получат разрешение на доступ к данным. Приоритеты читающих потоков не учитываются.
Существуют специальные вызовы, которые позволяют потоку тестировать возможность доступа к необходимой блокировке, оставаясь в активном состоянии (pthread rwlockt ryrdlock() и ptfiread_rwlock_trywrlock()). Эти вызовы возвращают код завершения, сообщающий о возможности или невозможности установки блокировки.
Реализация блокировок по чтению/записи происходит не в ядре, а посредством мьютексов и условных переменных, предоставляемых ядром.
Семафоры
Еще одним средством синхронизации являются семафоры (semaphores), которые позволяют потокам увеличивать (с помощью функции sem_post()) или уменьшать (с помощью функции sem_wait()) значение счетчика на семафоре для управления блокировкой потока (операции «post» и «wait» соответственно).
При вызове функции sem_wait() поток не блокируется, если счетчик имел положительное значение. При неположительном значении счетчика поток блокируется до тех пор, пока какой-либо другой поток не увеличит значение счетчика. Увеличение значения счетчика может выполняться несколько раз подряд, что позволяет уменьшать значение счетчика, не вызывая блокировки потоков.
Существенным отличием семафоров от других примитивов синхронизации является то, что семафоры безопасны для применения в асинхронной среде («async safe») и могут управляться обработчиками сигналов. Семафоры как раз подходят для тех случаев, когда требуется пробудить поток с помощью обработчика сигнала.
Другим полезным свойством семафоров является то, что они были определены для работы между процессами. Хотя мьютексы в QNX Neutrino тоже работают между процессами, стандарты POSIX рассматривают эту возможность как дополнительную функцию, которая может оказаться не переносимой между системами.
Полезной разновидностью семафоров является служба именованных семафоров (named semaphore service). Эта служба использует администратор ресурсов и позволяет применять семафоры между процессами, выполняемыми на разных машинах внутри сети.
Поскольку семафоры, как и условные переменные, могут в штатном порядке возвращать ненулевое значение из-за ложного пробуждения, для их корректной работы требуется использование цикла:
while (sem wait(&s) && errno == EINTR) <
do_critical_region();/* Значение семафора уменьшилось. */
Синхронизация с помощью алгоритма планирования
Применение алгоритма FIFO-планирования стандарта POSIX в системе без симметричной многопроцессорной обработки предотвращает выполнение критической секции кода одновременно несколькими потоками с одинаковым приоритетом. Алгоритм FIFO-планирования предписывает, что все потоки, запланированные к выполнению по этому алгоритму и имеющие одинаковый приоритет, выполняются до тех пор, пока они самостоятельно не освободят процессор для другого потока.
Такое «освобождение» процессора также может произойти в случае, когда поток блокируется в результате обращения к другому процессу за сервисом или при получении сигнала. Поэтому критическая секция кода должна быть тщательно проработана и документирована для того, чтобы последующее обслуживание этого кода не приводило к нарушению данного условия. Кроме того, потоки с более высоким приоритетом в том (или любом другом) процессе все же могут вытеснять потоки, выполняемые по алгоритму FIFO-планирования. Поэтому все потоки, которые могут «столкнуться» между собой внутри критической секции кода, должны планироваться по алгоритму FIFO с одинаковым приоритетом. При таком условии потоки могут обращаться к этой разделяемой памяти без необходимости делать предварительный явный запрос на синхронизацию.
Метод монопольного доступа неприменим в многопроцессорных системах, поскольку в таких системах несколько процессоров могут одновременно исполнить код, который в однопроцессорной машине был бы запланирован на последовательное исполнение.
Дата добавления: 2017-01-29 ; просмотров: 804 ; ЗАКАЗАТЬ НАПИСАНИЕ РАБОТЫ
Для чего происходит блокировка рда в чтении
Исследования проф. А. Н. Соколова убедительно показали, что повышение скорости чтения, которое достигается за счет подавления артикуляции, не только не снижает качество восприятия информации, но и способствует лучшему усвоению смысла благодаря преобладанию нагляднообразных представлений, т. е. работы мозга в новом обобщающем коде.
Исследователи, изучающие механизмы речи, разработали различные методы подавления артикуляции, их можно свести к трем группам.
1. Механическая, принудительная задержка артикуляции (например, в том, что язык зажимают между зубами, или удерживают в зубах какой-либо предмет, к примеру жевательную резинку, и т. п.). Недостаток этого метода для наших целей в том, что он в принципе позволяет затормаживать только периферическую часть речедвигательного анализатора, а центральная (мозговая) часть остается свободной. Поэтому полностью подавить артикуляцию при чтении по такому методу невозможно.
Механическая задержка артикуляции в том, что удерживают в зубах какой-либо предмет
2. Метод речедвигательных и речеслуховых помех, заключается в принудительном произнесении постороннего текста вслух при одновременном чтении про себя. Действие этих помех в том случае уже распространяется не только на периферическую, но и на мозговую часть речедвигательного аппарата, что является несомненным преимуществом этого метода по сравнению с предыдущим. Однако использовать и его для полного подавления артикуляции нецелесообразно, так как фактически один вид артикуляции заменяется другим, и на это тратится много энергии. В самом деле, проговаривание постороннего материала при чтении основного текста про себя, хотя и исключает возможность проговаривания читаемого текста, вместе с тем полностью занимает речедвигательный анализатор посторонними действиями, тогда как его участие в основном процессе чтения могло бы в значительной степени способствовать повышению качества восприятия необходимой информации.
3. Метод центральных речевых помех, или метод аритмического постукивания. Этот метод разработан проф. Н. И. Жинкиным и использован им при исследовании закономерностей внутренней речи. Суть метода в следующем. Читая про себя, испытуемый постукивает кистью руки специализированный ритм, не соответствующий обычной ритмике русской речи. Один из задаваемых здесь ритмов включает в себя двухтактное постукивание с четырьмя ударными элементами в первом такте и двумя — во втором и со значительным усилением удара на первом элементе каждого такта.
Этот постоянно слышимый аритмический рисунок акустического воздействия должен разрушать привычный ритм естественных мелодических речедвижений при чтении русского текста, т. е. стать помехой для любой артикуляции — и внешней и внутренней. Помеха здесь возникает в результате того, что слова в русском языке, составляющие речевой поток, обладают переменным, разноместным ударением. Такое аритмическое постукивание становится непреодолимой помехой внешней артикуляции. Главная особенность этого метода в том, что на деятельность речевых органов (губы, язык, глотка, гортань) непосредственно никакого воздействия не оказывается. Глотка, язык, гортань, губы — все механизмы речи остаются свободными, и при выстукивании рукой специального ритма вокруг соответствующих пунктов мозгового возбуждения в коре головного мозга возникает зона индуктивного торможения, которая делает невозможным произнесение читаемых слов, т. е. подавляет периферическую артикуляцию из центра. Чтобы разобраться в том, как это происходит, посмотрим, какие зоны мозга управляют процессами речи и ее пониманием.
В процессе чтения про себя испытуемый постукивает кистью руки в определенном постоянном режиме специализированный ритм
Современная нейропсихология различает речь сенсорную — понимание того, что говорит партнер, и речь моторную, — произнесение звуков речи самим человеком. Конечно, обе эти формы речи очень тесно связаны между собой, но все же они различаются по механизмам реализации их основных функций. Важно для нас также и то, что сенсорная и моторная речь управляются разными отделами мозга.
Еще в 1861 г. французский нейрохирург П. Брока обнаружил, что при поражении мозга в области второй и третьей лобных извилин (рис. 11) человек перестает членораздельно говорить и издает лишь бессвязные звуки, хотя сохраняет способность понимать то, что говорят другие. Эта речевая моторная зона, или зона Брока, у правшей находится в левом полушарии мозга, у левшей в большинстве случаев — в правом.
В 1874 г. другой учёный Э. Вернике установил, что есть зона и сенсорной речи. Поражения верхней височной извилины приводят к тому, что человек слышит слова, но перестает их понимать. Здесь утрачиваются логические связи слов с предметами и действиями, которые эти слова обозначают. При этом больной может механически повторять слова, не понимая их смысла. Эту зону мозга назвали зоной Вернике.
В зоне Вернике, как в своеобразной картотеке, хранятся все усвоенные в течение жизни человека звуковые образы слов. Конечно, они находятся там не буквально в виде цепочки закодированных слов (такое хранение неэкономично), а в виде так называемых нейронных следов звуковых образов. Всю жизнь человек пользуется этой картотекой. На рис. 11 показаны пути при произнесении слов нервных импульсов от речевых мышц и импульсов, идущих от уха. Этот рисунок показывает нам большое значение для нормальной работы мозга мышечных ощущений, возникающих при артикуляции. Как мы уже знаем, для быстрого чтения подавление артикуляции — обязательное условие. Очевидно, для его выполнения необходимо найти средство целенаправленного воздействия на зону Брока в процессе чтения с тем, чтобы преградить путь управляющим импульсам, поступающим из этой зоны для поддержания нормальной артикуляции. Как же добиться этого? Можно использовать аритмическое постукивание кистью руки. Как установили ученые, движения пальцев рук в ходе развития человечества оказались тесно связанными с речью. Первоначальной формой общении первобытных людей были жесты, язык жестов — праксис — постепенно стал сочетаться с гортанными возгласами, выкриками. Прошли тысячелетия, пока развилась словесная речь, но она долгое время была связана с жестикуляцией. Речевое сопровождение праксиса длилось долго.
Движения пальцев рук совершенствовались — из поколения в поколение люди выполняли все более тонкую и сложную работу. Одновременно с этим увеличивалась площадь двигательной проекции кисти руки (праксиса) в мозге человека. Развитие функций руки и речи шло параллельно и ими до сих пор управляет один нерв, так называемый нервус вагус (блуждающий нерв). Здесь уместно вспомнить известную мысль И. М. Сеченова о том, что “рука учит глаз”. Суть этой мысли в том, что рука как бы передает органу зрения гностический опыт осязания конкретных объектов внешнего мира. И. М. Сеченов блестяще показал, что естественной основой ритмики порядкового счета являются сигналы ритмических мышечных сокращений (получаемые, например, при ходьбе).
Выступая в роли своеобразного внутреннего метронома, такие сокращения не только подготавливают идею счета, но и входят в состав этого действия, как ритмоводитель.
О функциональной связи руки и глаза красноречиво говорит навык машинисток и линотипистов (наборщиков), которые умеют работать “слепым” методом. У них операции набора и перепечатки текста на больших скоростях не сопровождаются аналитическими действиями, касающимися смысла. Восприятие текста происходит блоками, и запечатлевается только стереотипный образ текста — его форма.
Известно также, что ребенок, осваивающий счет предметов, включает в этот процесс движения указательного пальца. При запрещении действовать рукой он не может сосчитать предметы, хотя и воспринимает их зрительно. Очевидно, что указательный жест несет безусловно важную функцию.
Указательный жест имеет как бы две стороны: внешнюю и внутреннюю. Внешняя сторона жеста — направление пальца на объект — фактически выделяет последнее: внутренняя сторона как бы обращена к организму и “вводит” этот объект в систему Моего Я, например счета в форме сигналов к активному мышечному сокращению в приемлемом ритме организма. Все это в равной степени относится и к описательным жестам, и к имитирующим.
Когда взрослый человек считает предметы глазами, то в роли указательных жестов руки выступают указательные движения глаз. Внешняя Сторона этих движений состоит в направлении взора на очередной объект, например строку текста, внутренняя — в производстве дискретных мышечных сигналов. Такие сигналы формируются в результате скачков, устанавливающих взор на нужную строку, и “сообщают” в мозг о каждой следующей строке. Более подробно вы узнаете об этом в следующей главе.
Исследования, проведенные в последние годы в Ленинграде проф. М. М. Кольцовой, показали, что речевые области мозга у детей в раннем возрасте частично формируются и под влиянием импульсов, поступающих от пальцев рук. Наблюдая детей в возрасте 10—12 месяцев, она установила, что их речь, образно говоря, находится на кончиках пальцев. Известно, что речь — это вторая сигнальная система, и она нам от рождения не дается. Если ребенка не учить говорить, он будет немым.
Проф. М. М. Кольцова рекомендует специальные упражнения для тренировки пальцев рук детей 6 — 7 месячного возраста. Благодаря этому ребенок гораздо раньше начинает произносить полные слова, обычно трудные для этого возраста. Таким образом, существует прямая и естественная связь между движением руки и произнесением слов.
Значит, здесь есть постоянное функциональное взаимодействие предметной и речевой информации, которое объяснено акад. И. П. Павловым как взаимодействие первой (предметной) и второй (речевой) сигнальных систем.
Теперь можно привести примеры, показывающие три различных способа реализации коммуникации: зрительный, слуховой, двигательный.
Представьте себе, что вы беседуете с приятелем, который пришел к вам по делу. Обсудив все вопросы, вы распрощались с ним. Он ушел. И вдруг вы вспомнили, что забыли сказать ему нечто важное. Нужно вернуть его. Как же можно это сделать, используя каждый из вышеназванных способов коммуникации?
Зрительный. Быстро набросав фламастером плакатик: “Вернись, пожалуйста!”, вы выходите на балкон и показываете его приятелю, который, выйдя из подъезда, обернулся на прощание помахать рукой, увидел вас, удивился странной форме обращения, но все же выполнил вашу просьбу.
Слуховой. Выйдя на балкон, вы просто крикнете: “Вернись, пожалуйста!”
Приведенное объяснение, конечно, весьма условно, но оно отражает основную идею метода постукивания: ритмические движения рукой запирают речедвигательный канал и артикуляция практически становится невозможной. Естественно, возникает вопрос: неужели читающие быстро все время так и постукивают при чтении? Конечно, нет. Достаточно 20 часов почитать с постукиванием ритма, чтобы созрела и окрепла новая программа работы мозга, сформировался новый стереотипный код, обеспечивающий обработку поступающей по зрительному каналу в мозг информации без ее проговаривания.
Главное в освоении метода — правильно разучить и выстукивать ритм. Для разучивания ритма необходимо вначале внимательно прочитать правила выполнения этого несложного упражнения, затем простучать сам ритм и многократно повторить его. Необходимо помнить, что эффект метода проявляется только в том случае, если читатель самостоятельно работает с текстом — непрерывно выстукивает ритм и контролирует правильность звучания на слух. Читать текст с выстукиванием можно только после того, как выучен ритм, для проверки правильности рисунка ритма надо контролировать его по нотной записи (рис. 13) и использовать специальное географическое пособие.
Как показывает наш опыт, при настойчивом и аккуратном выполнении упражнений, приведенных в конце главы, практически все обучающиеся достигают нужного эффекта. Для успешного подавления артикуляции, как правило, достаточно чтения с одновременным выстукиванием ритма в течение 20 часов. Однако в зависимости от типа нервной системы и других индивидуальных психофизиологических особенностей освоение упражнений протекает у некоторых обучающихся по-разному. Особенности выполнения этого упражнения будут рассмотрены в 9 главе (Урок пятый).
Уровни изоляции транзакций
— в деталях, но простыми словами.
Если понять 50%, а запомнить хотя бы 10% этой статьи, то на интервью ответить не составит труда.
В Аквелоне мы часто готовимся (и готовим) к различным проектам и интервью. Иногда всплывают темы, которые хотелось бы знать точнее, детальнее. Именно из такого исследования принципов ACID, а именно изолированности, и родилась эта статья.
Примечание: побочные эффекты и уровни изоляции параллельных транзакций в этой статье описаны согласно стандарту ANSI SQL. Способы реализации взяты из MS SQL.
Зачем это надо, и как оно появилось?
При изучении любого феномена, важно осознать в каких условиях он возник, что было “вокруг него” — тогда будет ясна мотивация создателей и цели, которые они преследовали.
За точку отсчёта возьмём начало семидесятых, когда Рэймонд Бойс (англ. Raymond Boyce, 1947–1974) и Дональд Чемберлин (англ. Donald D. Chamberlin) (род. 1944), работая в IBM, создают язык запросов SEQUEL (тот самые “сиквел”), позднее переименованный в SQL и впервые стандартизированный в 1986 как “SQL-86”.
Далее — понеслось. Сама IBM в этот язык и реляционную модель не поверила, зато её взяла за основу компания “Relational Software”, ныне всем известная как Oracle.
К середине восьмидесятых технический прогресс обеспечил возможность повсеместного использования реляционных БД, а к началу девяностых (рискну сказать “и по сей день”) они уже доминировали на рынке масштабного хранения и обработки данных.
Ещё тогда эти ребята придумали концепции транзакций, их свойства (ACID), и так далее. Одна из секций стандарта SQL как раз посвящена уровням изоляции, и даёт ответы на два главных вопроса:
Побочные эффекты
Стандарт даёт описания пяти побочных эффектов, сначала идут простые, затем более сложные. Под “сложностью” побочного эффекта я имею ввиду “сложнее его отловить и исправить”. Например отсутствие LOST UPDATE обеспечить проще, чем отсутствие DIRTY READ. Для понимания этих эффектов, надо держать в уме, что речь всегда идёт о взаимодействии двух и более транзакций одновременно, а сам побочный эффект — это когда желаемый результат не совпал с реальным.
Потерянное обновление / Lost Update
Когда несколько транзакций что-то обновили в БД, но по итогам результат такой, будто отработала лишь часть транзакций.
Самый опасный побочный эффект, по сути, полное отсутствие изоляции транзакций — две транзакции читают одну ячейку, записывают изменённое значение (одна вычитает стоимость мороженого, другая плату за квартиру). В итоге в ячейке значение от второй транзакции, а первой как будто и не было.
Грязное чтение / Dirty Read
Когда ваша транзакция может прочитать данные, которые были добавлены/изменены другой транзакцией, пока та ещё не вызвала COMMIT этих данных (ещё другая транзакция могла что-то удалить, тогда ваша транзакция перестанет это видеть).
Тоже опасный эффект—одна транзакция читает ячейку, обновляет её, другая считывает обновлённое значение, изменяет его, в это время первая транзакция откатывается, а вторая записывает результат, будто обе транзакции отработали.
Неповторяющееся чтение / Non-Repeatable Read
Когда одинаковый запрос в одной транзакции может вернуть разные данные; NON-REPEATABLE READ касается лишь только набора данных, который однажды уже был прочитан в транзакции — это значит, если вы прочитали первые 10 строк таблицы А, то NON-REPEATABLE READ случится, если вы заново прочитаете первые 10 строк таблицы А и получите другой результат;
Это уже менее опасный эффект, но более сложный в понимании. Допустим, одна транзакция считает полную стоимость услуги на основе тарифов, а другая меняет параллельно эти тарифы. Non-repeatable read случится, если последовательность действий будет такова:
Фантомное чтение / Phantom Reads
Когда: одинаковый запрос может вернуть НОВЫЕ строки, которые были закомичены из другой транзакции. Отличие от NON-REPEATABLE READ в том, что строки, которые мы уже разок прочитали остаются такими же, соответствнно здесь нет NON-REPEATABLE READ. Но при этом, запрос который сначала вернул 5 строк, может вернуть эти же пять строк, плюс ещё две свежие строки из другой транзакции — это PHANTOM READ;
Это ещё менее опасный эффект. Возникнуть он может в похожем на предыдущий примере, но если первая транзакция ещё ищет скидки, которые можно применить. Если сначала она найдёт три скидки, то Phantom Read возникнет, когда, впоследствии, этот же запрос может вернуть те же три скидки плюс одну новую.
Уровни изоляции
Уровни изоляции тоже описаны в стандарте, и они гарантируют отсутствие разных (с каждым разом всё более сложных) побочных эффектов.
При этом, “простые” эффекты включают в себя все более сложные, то есть если есть шанс на DIRTY READ, то и всё что сложнее его — можно тоже спокойно получить.
В прошлом сообщении эти эффекты описаны как раз в порядке возрастания “сложности”:
Исходя из этой таблицы можно определить режимы изоляции транзакций. Например: режим REPEATABLE READ — это такой режим, где гарантируется отсутствие любых побочных эффектов, кроме фантомных чтений.
Чем сложнее побочный эффект, тем сложнее его избежать. Соответственно, чем сильнее уровень изоляции, тем меньше производительность БД — потому что транзакциям чаще приходится ждать друг-друга.
Подходы к реализации уровней изоляции
Существует два глобально различных подхода к реализации изолированности: блокирование и версионирование.
Версионирование (snapshot) означает, что транзакции будут работать со своей копией данных, не влияя друг на друга, но впоследствии несколько изменённых копий надо будет как-то слить в одну. Строгость версионирования регулирует моменты (когда) и размеры (сколько данных копировать) этих копий.
Блокирование (lock) означает, что одна транзакция будет ждать другую, чтобы избежать побочных эффектов, в зависимости от строгости уровней изоляции этих транзакций. Различные виды блокировок обеспечивают более гранулярное блокирование, например, только по строкам, или только на небольшой кусочек транзакции, а не на всю.
В описаниях блокировок часто всплывает понятие оптимистичной и пессимистичной блокировки. Это два высокоуровневых термина, которые обозначают следующее:
Далее, рассмотрим подходы к блокировке/версионированию в MS SQL.
Реализация уровней изоляции в MS SQL
Давайте посмотрим, как уровни изоляции реализованы в Microsoft SQL Server.
Примечание 1: здесь начинается слабодокументированная зона, и я могу ошибаться, но готов вносить исправления и улучшать.
Примечание 2: возможно, эта глава будет расширена описанием shared-, exclusive-, range-locks: что это такое, в каком режиме и как оно используется.
Read Uncommitted
Ничего не происходит в режиме read uncomitted. То есть ничего не блокируется и не создаются снэпшоты, транзакция просто читает всё что хочет. По смыслу, этот режим можно отнести к (очень) оптимистичному — блокировки редки и коротки.
Read Committed
Read committed (то есть отсутсвие dirty reads) обеспечивается блокировкой на запись данных (строк), которые мы пытаемся прочитать. Эта блокировка гарантирует, что мы подождём завершения транзакций, которые уже меняют наши данные, или заставим их подождать, пока мы будем читать. В итоге, мы точно прочитаем только данные, которые были закоммичены, избежав тем самым грязное чтение. Этот режим — типичный пример пессимистичной блокировки, так как мы блокируем данные на запись, даже если в них никто реально не пишет.
Read Committed Snapshot
Read commited snapshot (второй способ избежать dirty reads) обеспечивается версионированием блока данных, который мы читаем. Любое его параллельное изменение на затронет нашу версию, и нам достанутся данные на момент начала чтения. Таким образом грязное чтение отсутствует, и ещё отсутствуют какие-либо блокировки*. Этот режим скорее оптимистичный, так как заранее ничего не блокируется, и тут как раз может быть конфликт обновления.
Repeatable Read
Repeatable read (то есть отсутствие всего, кроме фантомных чтений) обеспечивается почти как read commited, за тем исключением, что блокировка на запись работает до конца транзакции, а не отдельной операции. Единожды “коснувшись” блока данных, транзакция блокирует его изменение до конца работы, что обеспечивает отсутствиуе dirty reads и non-repeatable reads. Это более пессимистичный вид блокировки, чем read committed, так как блокировка держится ещё дольше.
Serializable
Serializable (нет никаких побочных эффектов) обеспечивается блокировкой и на запись, и на чтение любого блока данных, с которым мы работаем. Блокируется даже вставка данных, которые могут попасть в блок, который мы прочитали. Таким образом, за счёт низкой конкурентности, обеспечивается отсутствие даже фантомных чтений. Это более пессимистичный вид блокировки, чем repeatable read, так как блокировка держится ещё дольше.
Snapshot
Snapshot обеспечивается созданием нашей отдельной версии данных, с которыми мы работаем, без блокировок*. Другие транзакции не будут иметь доступ к нашей версии, чем и обеспечивается отсутствие всего вплоть до фантомных чтений. Это оптимистичный вид блокировки, но менее оптимистичный, чем read committed snapshot, так как больше шансов получить конфликт обновления.
Примечания
Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table ‘dbo.Table’ directly or indirectly in database ‘DB’ to update, delete, or insert the row that has been modified or deleted by another transaction. Retry the transaction or change the isolation level for the update/delete statement.
Заключение
Обо мне
Меня зовут Рустем, последние несколько лет работаю проект-менеджером в Аквелоне. Ещё у меня более 10-ти лет опыта разработки софта и других классных штук. Связаться со мной можно через twitter.com/rulikkk или подписаться на мой канал в tg: techno_ru.
Полезные ссылки
По этим ссылкам, а также пользуясь здравым смыслом, я и собрал статью: