@dba_ru

Страница 251 из 718
Alexey
18.09.2017
13:28:42
Пардон, там не уникальный индекс. Просто табличка с полями дата (без времени), тип и ItemCount int, и кластерный ПК по всем этим трём полям.

Ilia
18.09.2017
13:29:17
дата+ тип документа = pk таблицы-счетчика
Так это PK, а не уникальный индекс. Уникальный индекс — это что ПОМИМО PK

Alexey
18.09.2017
13:29:26
Если цикл не делать, то 5-6 документов из 4000 при тесте не вставляются, т.к. происходит ошибка, то самое задвоение

Google
Alexey
18.09.2017
13:29:45
Не должно такого быть.
Поясни (повтори, если уже было) пож почему?

キリル
18.09.2017
13:30:05
pk автоматически подразумевает уникальный индекс на поле или набор полей

Ilia
18.09.2017
13:30:09
Вот в этом и проблема. Код давай, тогда поговорим

Поясни (повтори, если уже было) пож почему?
По построению этого решения.

С какого перепугу ты цикл добалял ? Для чего?

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

Всё

Alexey
18.09.2017
13:33:02
Хм, дело. Перевариваю.

キリル
18.09.2017
13:41:35
Входящие транзакции вставки должны сериализоваться на изменении нового номера в таблице-генераторе, и получении его назад, поэтому никаких вставок с левыми (неправильными) номерами документов просто не может быть.
если после каждого инсерта в таблицу документов коммит не делать, то параллельные сессии будут пытаться вставить одинаковые номера в рамках дня и типа документа. ввиду изоляции транзакций измененнные данные в таблице-генераторе им не видны и начинаться будет всегда с начала счетчика(или последнего закомиченного значения)

キリル
18.09.2017
13:42:31
update тоже в транзакции работает

Ilia
18.09.2017
13:42:42
Безусловно.

Google
Ilia
18.09.2017
13:43:01
Напомни мне ещё, НА КАКОМ УРОВНЕ ИЗОЛЯЦИИ UPDATE работат, а ?

キリル
18.09.2017
13:48:50
натурный эксперимент сессия1: create table t1(p1 integer); create unique index i_t1 on t1(p1); insert into t1 values(1); commit; update t1 set p1=p1+1 where p1=1; заинсертилось сессия 2: update t1 set p1=p1+1 where p1=1; блокировка

ничего неожиданного

Ilia
18.09.2017
14:00:22
Ну, так блокируется UPDATE, всё ОК?

Alexey
18.09.2017
14:36:26
Ох, перекопал ещё раз всё, а то мне тут понаговорили, что у меня 100%-ая какашка и надо делать Update. Но ведь в условии сказано, что сессии не должны ждать друг друга. А если будет блокировка update внутри транзакции, то будет ожидание одной сессией, пока завершиться транзакция в другой сессии. А при инсерте такого не будет. Есть аргументы на эту мысль?

Ilia
18.09.2017
14:40:42
А за счёт чего ты будешь новый идентификатор генерировать в таком случае?

МОжет я не понял, ты объясни...

Alexey
18.09.2017
14:41:09
Ты видел мой код, там написано за счёт чего

Ilia
18.09.2017
14:41:29
Я не понял. Ладн, ща посмотрю.

Alexey
18.09.2017
14:42:12
*Я могу тут расписать всё, но мне кажется быстрее будет в коде разобраться :)

Ilia
18.09.2017
14:42:47
(Напоминаю, что код вижу только я)

Alexey
18.09.2017
14:43:59
хм, я смогу его всем только завтра показать ближе к полуночи желающим могу кинуть в личку

Там вся суть, что я вместо апдейта таблицы с хранлищем номером, произвожу инсерт в неё. А потом беру номер для нового документа так select @ItemIndexMax = max([ItemIndex]) from dbo.[Numbers] where [Date] = @Date and [TypeId] = @TypeId

Ilia
18.09.2017
14:45:40
Ну блин, там у тебя дофига мелких ошибок, не может это всё работать.

Alexey
18.09.2017
14:45:47
=D

Опять мелких ошибок

Ilia
18.09.2017
14:46:16
Как бы тут такая вещь, что все детали очень важны.

Alexey
18.09.2017
14:46:26
эта логика оправдывает мой пк на три поля, оправдывает цикл и что там ещё было не оправдывает только отсутствие отката транзакции при raiserror, там да, косяк

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

Ilia
18.09.2017
14:48:28
вот выбрал ты очередной номер, вот вставляешь его обратно в таблицу: insert into dbo.[VelesTestDocsNumbers] ( Выбраться могут параллельно два одинаковых ключа. Вставиться — нет, у тебя там ключ первичный по новому ID. НО ты результат вставки нифига не проверяешь.... Если оно НЕ вставилось, ты так дальше и почапаешь...

Google
Ilia
18.09.2017
14:48:45
set transaction isolation level read uncommitted — - НАФИГА ? Нет, нормально...

Alexey
18.09.2017
14:49:10
да всё для того же =D

и как же не проверяю результат вставки? там же try catch стоит. Не вставится, будет ошибка, попробуем ещё раз.

Ilia
18.09.2017
14:49:45
У тебя тут вообще-то SERIALIZABLE должно было бы быть, а не READ UNCOMMITED>

Я современный MS плохо знаю.

(это видимо он)

Alexey
18.09.2017
14:51:01
SERIALIZABLE - но ведь это самый высокий уровень изоляции. Тогда точно условие "сессии не должны ждать друг друга" не будет выполнено.

Ilia
18.09.2017
14:51:20
Оно должно быть на одном операторе.

Fike
18.09.2017
14:53:44
Всем привет. Есть задачка. Я её решил по своему, мои тесты прошли. Но мне сказали, что я с ней не справился, пока без уточнения подробностей. Мб кто подскажет другое решение? (своё пока не открываю) Есть табличка с кучей записей, и туда постоянно вставляют новые записи, очень часто. Каждая строка это документ, и у этого документа есть уникальный номер (varchar(32)), который формируется из даты его создания, его типа (А, Б, С, ...) и порядкового номера (int). И этот порядковый номер меняется от 1 до N в рамках дня создания(!) и типа документа(!). Т.е. номера, например, будут такие: 20170917/А-1 20170918/А-1 20170918/А-2 20170918/Б-1 20170918/С-1 20170918/С-2 20170918/С-3 20170919/А-1 ... Уникальный индекс на этот номер вешать нельзя по условию. При проверке запускается тест скрипт, четыре раза из четырёх разных сессий, который в цикле, с задержкой 50мс или около того, вставляет записи в эту табличку. Как реализовать заполнение такой таблички с формирлованием такого номера для каждого документа, но что бы не было задвоения этих номеров?
0. Поставить READ COMMITTED 1. Получить максимальное значение за день 2. id = максимальное значение + 1 3. Вставить запись с указанным id 4. Проверить количество совпадений, если больше одного, откатить транзакцию и повторить

5. Вызвать на дуэль того домового, который придумал запрет на уникальный индекс

Alexey
18.09.2017
14:55:25
0. Поставить READ COMMITTED 1. Получить максимальное значение за день 2. id = максимальное значение + 1 3. Вставить запись с указанным id 4. Проверить количество совпадений, если больше одного, откатить транзакцию и повторить
В условии есть пункт "сессии не должны ждать друг друга". При READ COMMITTED это будет не так. Даже более того, там повесили тригер на инсерт, делающий задержку после каждого инсерта в 10 мс.

Fike
18.09.2017
14:55:38
почему они ждать-то будут?

Alexey
18.09.2017
14:55:44
Alexey
18.09.2017
14:56:00
хочется плакать
поясни, плиз мб я не понимаю чего-то

lost
18.09.2017
14:56:08
латенси в триггерах - новый вид наркомании

о таком я еще не думал

Fike
18.09.2017
14:56:25
ну в принципе можете и понизить уровень изоляции, просто ложных срабатываний прибавите

Alexey
18.09.2017
14:57:27
Я просто напомню, что это именно задачка, а не практический пример. Поэтому извращение с тригером, задержками и запретом на уникальный индекс.

Google
Alexey
18.09.2017
14:57:37
желающим, могу кинуть код (задания и решения), только напишите в личку

Fike
18.09.2017
14:58:32
ну у вас ровно два решения

оптимистичная блокировка и пессимистичная блокировка

я предлагаю оптимистичную

Alexey
18.09.2017
14:59:27
крутые термины, секунду, прогуглю)

Fike
18.09.2017
14:59:29
ждать оно нигде не должно, write-локи если и есть, то только на добавляемые записи

Ilia
18.09.2017
15:00:13
А я - пессимистичненькую : )

Fike
18.09.2017
15:01:20
Да что там гуглить. Пессимистичная: сделаем все операции внутриэксклюзивно взятого ресурса. Оптимистичная: попробуем добавить, а если инвариант не выполнился, откатим.

Пессимистичная, кстати, у вас прям по задаче невозможна

лол

Ilia
18.09.2017
15:01:46
я предлагаю оптимистичную
На оптимисте могут быть транзакции, зависшие в состоянии "я пытаюсь вставить запись"

Fike
18.09.2017
15:01:51
Потому что при пессимстичной они будут вынуждены ждать друг друга

На оптимисте могут быть транзакции, зависшие в состоянии "я пытаюсь вставить запись"
А еще хдд может отвечать что записывает, но на самом деле он Доктор Зло и ничего не записывает, такой у него хитрый план

мы не рассматриваем плохо работающую систему в рамках задачи

Al
18.09.2017
15:03:23
Всем привет. Есть задачка. Я её решил по своему, мои тесты прошли. Но мне сказали, что я с ней не справился, пока без уточнения подробностей. Мб кто подскажет другое решение? (своё пока не открываю) Есть табличка с кучей записей, и туда постоянно вставляют новые записи, очень часто. Каждая строка это документ, и у этого документа есть уникальный номер (varchar(32)), который формируется из даты его создания, его типа (А, Б, С, ...) и порядкового номера (int). И этот порядковый номер меняется от 1 до N в рамках дня создания(!) и типа документа(!). Т.е. номера, например, будут такие: 20170917/А-1 20170918/А-1 20170918/А-2 20170918/Б-1 20170918/С-1 20170918/С-2 20170918/С-3 20170919/А-1 ... Уникальный индекс на этот номер вешать нельзя по условию. При проверке запускается тест скрипт, четыре раза из четырёх разных сессий, который в цикле, с задержкой 50мс или около того, вставляет записи в эту табличку. Как реализовать заполнение такой таблички с формирлованием такого номера для каждого документа, но что бы не было задвоения этих номеров?
Какая редкостная хрень. И кто и зачем придумал этот бред?

Alexey
18.09.2017
15:04:04
Какой ответ ты хочешь на этот вопрос?

lost
18.09.2017
15:06:57
вы хотите не ждать в mvcc, это взаимоисключающие параграфы

Alexey
18.09.2017
15:06:59
Etki, Ilia Zviagin, и другие - спасибо за инфу, переварю. Я пока убегаю. Завтра, если кому будет интересно, поделюсь какое решение предполагали авторы задачи.

Fike
18.09.2017
15:07:47
lost
18.09.2017
15:08:42
а по-идее не в каждой бд можно манагер блокировок затюнить

Google
lost
18.09.2017
15:08:51
он же де-факто пессимистичный

Alexey
18.09.2017
15:10:55
мне очень важно твоё мнение, я тебе обязательно перезвоню

Al
18.09.2017
15:14:54
Решение видимо очень простое. Заводим табличку счетчик. Читаем номер прибавляем 1. Вставляем новый номер для следующих сессий

В смысле все табличка из 1 строки с порядковым номером. Каждый день обнуляем его. Видел как то такой вариант. О.о

lost
18.09.2017
15:21:22
понижать изоляцию(типа ставить возможным read uncommited) это же моветон
я не совсем понимаю как уровень изоляции связан с поведением блокировщика

и в некоторых случаях приходится делать такое

キリル
18.09.2017
15:23:45
да это я вернулся обратно в теме с пробелами в счетчике. у нас тут случилось разногласие по поводу видит ли 1 апдейт из 1 сессии данные другого

Какая изоляция транзакций, если там UPDATE ?

update тоже в транзакции работает

Да
я в одном проекте секвенс делал на таблице с автоинкрементом. хрень редкостная. после оракла с его секвенсами

キリル
18.09.2017
15:28:08
тогда я не понял то что вы мне хотели донести. все хорошо и все довольны))

Dmitriy
19.09.2017
06:40:03
Коллеги. На оракле кто то почистил таблицу, можно ли узнать кто? или хоть что, последние запросы и т.д.

Ilia
19.09.2017
07:02:01
Зависит от...

Страница 251 из 718