Федя пишет:
> Спасибо, с транзакциями я разобрался — все работает. Но есть ли другой > способ?
Это — лучший.
Не хотелось бы блокировать таблицы на время чтения всех дочерних > записей.
Тебе кто-то что -то говорил про блокирование ? с чего ты взял,
что что-то будет блокироваться ?
(только тут мне надо бы напомнить, с какой версии MSSQL
snapshot isolation поддерживает).
Нужна какая-то "оптимистичная" проверка. Чтобы можно было > читать все таблицы по очереди, в предположении, что ничего не > поменялось. А потом на стороне клиента сравнивать версии строк и заново
Ну есть еще т.н. "оптимистическая блокировка по timestamp".
Можно применить ее. Но что-то я сейчас уже не соображу,
как можно и можно ли вообще это применить для твоего
конкретного случая.
> читать изменившиеся строки (их скорее всего будет немного).
И что с ними потом будешь делать ? Ничего уже делать нельзя.
Либо ты НЕ имеешь конфликт, тогда можно сохранять. Либо имеешь,
тогда транзакцию твою надо сначала запускать,заново.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Соответствие версий родительских и дочерних записей
Федя пишет:
меняет, то > иногда получается так, что версии дочерних записей могут не > сответствовать версиям родительских записей. Напрмер кто-то удалил > строку из дочерней таблицы уже после того как загрузилась родительская
Если ты все данные для этой формы будешь получать в одной транзакции,
и при этом она будет на нужном уровне изоляции, то такого никогда не
будет.
> таблица. Хотелось бы научиться определять такие коллизии и заново > загружать обновившиеся документы (возможна другая реакция, не важно).
Такую коллизию ты можеш обнаружить ТОЛЬКО ПРИ СОХРАНЕНИИ ДАННЫХ ОБРАТНО.
и реакция может быть только одна — отмена сохранения этих данных
(есть второй вариант — сохранение данных не смотря на обнаруженную коллизию).
> Вариант с транзакциями не катит, т.к. во первых используется стандартный > DataAdapter, а во вторых я думаю такой подход существенно снизит > производительность приложения из-за блокировок.
Уперед. Пока человечество ничего лучше транзакций не придумало. Придумаешь --
ну, премия Тьюринга, думаю, как минимум.
Posted via RSDN NNTP Server 2.1 beta
Re[7]: Соответствие версий родительских и дочерних записей
Федя пишет: > W>А зачем запрашиваются дочерние таблицы, ведь форма отображает только > данные из главной? (или нет?) > > нет, загружается все сразу и главная и все дочерние записи
Тут надо понимать, что такое "сразу". "Сразу" — это в одной
транзакции, обеспечивающей согласованное чтение этих данных.
Иначе — не сразу. Если у тебя эта транзакция есть,
то тебе более ничего и не нужно (ну может еще оптимистическая
блокировка по timestamp или по всем неключевым полям).
Если нет — тебе уже нично не поможет, данные и так уже не
согласованные.
> Если ты намекаешь про то что два пользователя могут одновременно менять > один документ, то нет, т.к. есть соответствующая проверка. Читается > timestamp строки документа и при сохранении изменений проверяется не > изменился ли он в базе. Также есть триггеры которые меняют timestamp в > родительской строке при изменении дочерних записей.
В общем, как говорится, есть десять (10) категорий людей.
Которые знают двоичную систему счисления, и которые не знают.
Так же и с этим. Есть люди, понимающие, что такое транзакции, и еще
нет. Это -- типичные проблемы человека, не понимающего. Надо читать
что-то теоретическое, хотя бы немного.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Соответствие версий родительских и дочерних записей
Здравствуйте, Федя, Вы писали:
Ф>Кстати, не сочтите за издевательство, думаю вы поймете. А что, если между чтениями из базы кто-то переведет часы?
Нет, не сочтем, хоть это и смешно; я сталкивался с таким случаем. Между чтениями на сервере БД прошла синхронизация времени, причем "назад". Приложение, обнаружив при следующем обращении, что "время пошло вспять", не перенесло такого и упало.
Для решения этой проблемы можно вместо времени использовать последовательность целых чисел.
Re[4]: Соответствие версий родительских и дочерних записей
Здравствуйте, MasterZiv, Вы писали:
MZ>Федя пишет: >> MZ>Выполнить два запроса в одной транзакции. >> >> Не понял, а как транзакции влияют на select?
MZ>Непосредственно. Или ты думал, что SELECT — это не транзакция ?
Я уже исправился
Re[4]: Соответствие версий родительских и дочерних записей
Здравствуйте, MasterZiv, Вы писали:
MZ>Федя пишет:
>> Спасибо, с транзакциями я разобрался — все работает. Но есть ли другой >> способ?
MZ>Это — лучший.
Не в моем случае
MZ>Не хотелось бы блокировать таблицы на время чтения всех дочерних >> записей.
MZ>Тебе кто-то что -то говорил про блокирование ? с чего ты взял, MZ>что что-то будет блокироваться ?
А как по твоему работает транзакция?
MZ>Нужна какая-то "оптимистичная" проверка. Чтобы можно было >> читать все таблицы по очереди, в предположении, что ничего не >> поменялось. А потом на стороне клиента сравнивать версии строк и заново
MZ>Ну есть еще т.н. "оптимистическая блокировка по timestamp". MZ>Можно применить ее. Но что-то я сейчас уже не соображу, MZ>как можно и можно ли вообще это применить для твоего MZ>конкретного случая.
вот и соображай
>> читать изменившиеся строки (их скорее всего будет немного).
MZ>И что с ними потом будешь делать ? Ничего уже делать нельзя. MZ>Либо ты НЕ имеешь конфликт, тогда можно сохранять. Либо имеешь, MZ>тогда транзакцию твою надо сначала запускать,заново.
речь не идет о сохранении, читай внимательно
Re[8]: Соответствие версий родительских и дочерних записей
Здравствуйте, MasterZiv, Вы писали:
MZ>Федя пишет: >> W>А зачем запрашиваются дочерние таблицы, ведь форма отображает только >> данные из главной? (или нет?) >> >> нет, загружается все сразу и главная и все дочерние записи
MZ>Тут надо понимать, что такое "сразу". "Сразу" — это в одной MZ>транзакции, обеспечивающей согласованное чтение этих данных. MZ>Иначе — не сразу. Если у тебя эта транзакция есть, MZ>то тебе более ничего и не нужно (ну может еще оптимистическая MZ>блокировка по timestamp или по всем неключевым полям). MZ>Если нет — тебе уже нично не поможет, данные и так уже не MZ>согласованные.
Сразу значит, при загрузке формы, но в разных транзакциях.
>> Если ты намекаешь про то что два пользователя могут одновременно менять >> один документ, то нет, т.к. есть соответствующая проверка. Читается >> timestamp строки документа и при сохранении изменений проверяется не >> изменился ли он в базе. Также есть триггеры которые меняют timestamp в >> родительской строке при изменении дочерних записей.
MZ>В общем, как говорится, есть десять (10) категорий людей. MZ>Которые знают двоичную систему счисления, и которые не знают.
MZ>Так же и с этим. Есть люди, понимающие, что такое транзакции, и еще MZ>нет. Это -- типичные проблемы человека, не понимающего. Надо читать MZ>что-то теоретическое, хотя бы немного.
Интересно, пользователи Kvazimodo75 и . сразу дорубили в чем дело, а вам с товарищем wildwind приходится все разжевывать. На это не обратили внимание?
Re[6]: Соответствие версий родительских и дочерних записей
Здравствуйте, wildwind, Вы писали:
W>Здравствуйте, Федя, Вы писали:
Ф>>Кстати, не сочтите за издевательство, думаю вы поймете. А что, если между чтениями из базы кто-то переведет часы?
W>Нет, не сочтем, хоть это и смешно; я сталкивался с таким случаем. Между чтениями на сервере БД прошла синхронизация времени, причем "назад". Приложение, обнаружив при следующем обращении, что "время пошло вспять", не перенесло такого и упало.
W>Для решения этой проблемы можно вместо времени использовать последовательность целых чисел.
тоже, в принципе рабочий вариант
Re[11]: Соответствие версий родительских и дочерних записей
Федя wrote:
> Т.е. загружаем документы, запоминаем версии, потом загружаем части, а > потом опять загружаем документ и проверяем изменилась ли версия? Да, это > нормальный вариант. Единственное я хотел бы избежать двойной загрузки > базовой таблицы, т.к. это немного дольше.
Тебе не надо загружать всю таблицу. 3 пунктом достаточно запроса "select rev from Doc where id=?", а это вещь очень быстрая.
> Можно объединять дочерние записи с базовой таблицей, чтобы читать версии > документа сразу с загрузкой дочерних строчек. Только если дочерних > строчек у документа нет, то нет и версии Не могу пока ничего придумать.
Так предложенное мною решение это обнаруживает.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Соответствие версий родительских и дочерних записей
MasterZiv wrote:
> Если ты все данные для этой формы будешь получать в одной транзакции, > и при этом она будет на нужном уровне изоляции, то такого никогда не > будет.
Не врубился ты. Вот объясняю на пальцах.
begin transaction с самым крутым isolation level
select id, val from DocPart1 where parentId=5;
//выбираем список частей 1, он соответствует документу 5.
// в этот момент времени кто-то в другой транзакции удаляет весь документ 5 и все его части.
select id, weigh from DocPart2 where parentId=5;
//список частей пуст! Т.к. всё удалено. И никакие транзакции тут не помогут.
Получилось, что документ 5 отобразится пользователю со правильным списком частей 1 и с пустым списком частей 2. Что и является ошибкой с т.з. предметной области.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[7]: Соответствие версий родительских и дочерних записей
если оба селекта обернуть в транзакцию с "самым крутым" isolation level
никто ничего не удалит пока она не завершится
> Не врубился ты. Вот объясняю на пальцах. > > begin transaction с самым крутым isolation level > >
>
> select id, val from DocPart1 where parentId=5;
>
> //выбираем список частей 1, он соответствует документу 5.
>
> // в этот момент времени кто-то в другой транзакции удаляет весь
> документ 5 и все его части.
>
> select id, weigh from DocPart2 where parentId=5;
>
> //список частей пуст! Т.к. всё удалено. И никакие транзакции тут не
> помогут.
>
>
> > Получилось, что документ 5 отобразится пользователю со правильным > списком частей 1 и с пустым списком частей 2. Что и является ошибкой с > т.з. предметной области. >
Posted via RSDN NNTP Server 2.1 beta
Re[8]: Соответствие версий родительских и дочерних записей
Здравствуйте, Dianbi, Вы писали:
D>если оба селекта обернуть в транзакцию с "самым крутым" isolation level D>никто ничего не удалит пока она не завершится
да, это понятно, вот пример
В одном окне Query Analizer запускаем
create table Parent(ParentId int)
create table Child(ParentId int)
insert Parent values(1)
insert Parent values(2)
insert Parent values(3)
insert Child values(1)
insert Child values(2)
insert Child values(3)
set transaction isolation level repeatable read
begin tran
select * from Parent
declare @i int
set @i = 0
while @i < 100000 set @i = @i + 1
select * from Child
commit tran
drop table Parent
drop table Child
и, пока читает, в другом окне
begin tran
delete Parent
delete Child
commit tran
Давайте с транзакциями не будем продолжать, интересует вариант без них.
Re[12]: Соответствие версий родительских и дочерних записей
Здравствуйте, ., Вы писали:
.>Федя wrote:
>> Т.е. загружаем документы, запоминаем версии, потом загружаем части, а >> потом опять загружаем документ и проверяем изменилась ли версия? Да, это >> нормальный вариант. Единственное я хотел бы избежать двойной загрузки >> базовой таблицы, т.к. это немного дольше. .>Тебе не надо загружать всю таблицу. 3 пунктом достаточно запроса "select rev from Doc where id=?", а это вещь очень быстрая.
Да, это хорошая идея. Но у меня where, в запросе к основной таблице может быть достаточно сложный, не хотелось бы его два раза запускать. Или брать ID и на каждый документ по запросу? Тоже не гуд.
>> Можно объединять дочерние записи с базовой таблицей, чтобы читать версии >> документа сразу с загрузкой дочерних строчек. Только если дочерних >> строчек у документа нет, то нет и версии Не могу пока ничего придумать. .>Так предложенное мною решение это обнаруживает.
да, я понял
Re[8]: Соответствие версий родительских и дочерних записей
Dianbi wrote:
> если оба селекта обернуть в транзакцию с "самым крутым" isolation level > никто ничего не удалит пока она не завершится
repeatable read гарантирует чтение одних и тех же данных с одинаковым результатом.
Он не блокирует всю базу, а только использованные таблицы, а чаще только использованные строки таблицы, так называемый rowlevel lock. Факт чтения из DocPart1 никоим образом не повлияет на результаты чтения из DocPart2! И совершенно неважно какой уровень транзакции.
>> Не врубился ты. Вот объясняю на пальцах.
И ты не врубился. Поэкспериментируй на досуге.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Соответствие версий родительских и дочерних записей
Здравствуйте, ., Вы писали:
.>Dianbi wrote:
>> если оба селекта обернуть в транзакцию с "самым крутым" isolation level >> никто ничего не удалит пока она не завершится .>repeatable read гарантирует чтение одних и тех же данных с одинаковым результатом. .>Он не блокирует всю базу, а только использованные таблицы, а чаще только использованные строки таблицы, так называемый rowlevel lock. Факт чтения из DocPart1 никоим образом не повлияет на результаты чтения из DocPart2! И совершенно неважно какой уровень транзакции.
>>> Не врубился ты. Вот объясняю на пальцах. .>И ты не врубился. Поэкспериментируй на досуге.
Да, но в нашем случае, поскольку при обновлении частей документа всегда идет обращение к базовой строке для увеличения номера версии, то транзакция, изменяющая запись, будет ждать, пока все не прочитается. Конечно при условии, что опреация изменения номера версии будет в одной транзакции с редактированием дочерних записей.
Re[9]: Соответствие версий родительских и дочерних записей
Здравствуйте, ., Вы писали:
.>repeatable read гарантирует чтение одних и тех же данных с одинаковым результатом.
FYI: RR — не является "самым крутым уровнем изоляции" (с)
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Соответствие версий родительских и дочерних записей
Федя wrote:
> Да, но в нашем случае, поскольку при обновлении частей документа всегда > идет обращение к базовой строке для увеличения номера версии, то > транзакция, изменяющая запись, будет ждать, пока все не прочитается. > Конечно при условии, что опреация изменения номера версии будет в одной > транзакции с редактированием дочерних записей.
А, ну да. Если первой командой в изменяющей транзакции делать "update Doc set rev=rev+1", а первой читающей делать "select * from Doc" и isolation level >= repeatable read, то да, заработает, т.к. первым шагом оно будет лочить одну и ту же сущность. Но это на блокировочнике mssql, как интересно будет работать версионник?..
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[11]: Соответствие версий родительских и дочерних записей
Здравствуйте, ., Вы писали:
.>Федя wrote:
>> Да, но в нашем случае, поскольку при обновлении частей документа всегда >> идет обращение к базовой строке для увеличения номера версии, то >> транзакция, изменяющая запись, будет ждать, пока все не прочитается. >> Конечно при условии, что опреация изменения номера версии будет в одной >> транзакции с редактированием дочерних записей. .>А, ну да. Если первой командой в изменяющей транзакции делать "update Doc set rev=rev+1", а первой читающей делать "select * from Doc" и isolation level >= repeatable read, то да, заработает, т.к. первым шагом оно будет лочить одну и ту же сущность. Но это на блокировочнике mssql, как интересно будет работать версионник?..
видимо, не будет блокировать записи для изменений
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[12]: Соответствие версий родительских и дочерних записей
Федя wrote:
> видимо, не будет блокировать записи для изменений
Т.е. такой подход не прокатит? Или в читающей транзакции делать "select * from Doc for update", чтобы заставить заблокировать?
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай