Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Блокировка таблиц в хранимой процедуре?

Добрый день, коллеги!

Судя , в хранимых процедурах нельзя использовать блокировку таблиц.

Есть хранимка, в которой пересчитываются некоторые итоговые цифры и новые их значения записываются в итоговую InnoDB-таблицу.
Запускается эта процедура редко, но может быть запущена из прикладной проги пользователем с правами админа.
Естественно, в такие моменты база не закрыта и другие пользователи могут выполнять операции, которые могут использовать/изменять данные из вышеназванной итоговой таблицы.
Хотелось бы на время выполнения этой хранимки запретить другим пользователям изменять вышеназванную итоговую табличку.

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

Если я правильно понял, то единственный выход - на клиенте запускать эту хранимку в одном SQL-запросе вместе с блокировкой:
LOCK TABLES Table1 WRITE; CALL reCalcProc(); UNLOCK TABLES
Честно говоря, не нравится мне этот код - хотел бы все действия, необходимые для правильной и корректной обработки, "запаковать" в один "контейнер"!

Может кто чего посоветовать по этому поводу?

Спасибо!
Ответ:
tanglir
OlegROA,

select for update? Правда, я не уверен, будет ли он работать в процедурах. Вроде бы должен, только процедуру надо запускать в транзакции.



будет.
Вопрос: Вставка записи с автоинкрементом с блокировкой

Задача. Есть только удаленное подключение к БД, к определенным таблицам.
Есть таблица АAA.
Записать в нее данные, с уникальным полем ID.
Как я делаю сейчас:
'SELECT * FROM (SELECT ID FROM AAA ORDER BY ID DESC) WHERE ROWNUM <= 1';
Получив ID, увеличиваю его на 1.
$id++;
Далее вставляю запись.
'INSERT INTO AAA (ID,DATA) VALUES ($id,$data)';
По коду конечно отличается немного, суть такая, упростил для понимания.

Возникла проблема - в процессе работы появились записи с дублирующим ID.
Как избежать этого?

Я с Ораклом глубоко на "вы", работаю с mysql.
Думаю может надо так:
1. определяю, заблокирована таблица или нет. если да, то выходим.
2. ставим блокировку таблицы.
3. определяю новое ID
4. вставляю запись
5. Снимаю блокировку.

Но как это реализовать и правильно ли так не пойму. Требуется помощь :)
Ответ:
кому
вместо одного апдейта

Ну да типа
UPDATE table1 SET id = id + 1 RETURNING id INTO some_var;

На то он и есть жескач и да не отлаженный и не оптимальный и вообще plsql )
А какие более нормальные варианты не plsql? select max() с попытками блокировки таблицы? )
Вопрос: Блокировка таблицы базы или как правильно?

Привет!

Решаю нубскую задачу. Клиент читает запись из таблицы сли не находит ее, то добавляет. Как сделать чтобы исключить добавление дублирущей записи из разных процессов? В смысле как сделать правильно? Добавить уникальный составной ключ а в коде ловить исключение? Или как-то на уровне блокировок грамотней будет?
Ответ: Технически все сводится к блокировкам - что ключ, что applock.
А вот с архитектурой приложения беда.
Вопрос: блокировка таблицы на изменения

Подскажите, пожалуйста, как правильно внутри транзакции сделать блокировку всей таблицы от внесения изменений другими процессами? Чтобы другие процессы могли читать данные из этой таблицы, но не могли в ней производить insert/update/delete

MSSQL2014, VS2013, msoffice2007
Ответ: Leax,

ок, ясно,
но спасибо надо invm,
у меня не блокируется *вся* таблица,
или надо select *, или tablock в довесок,
короче, вариант invm берите
Вопрос: Блокировка таблицы

Подскажите, есть ли в скуле возможность заблокировать таблицу на изменение, к примеру просто задать значение "Запретить на изменение". не используя разрешения и без костылей типо триггеров. Просто задав параметр. Я искал, но что-то не нашел.
Ответ: Minamoto, интересовало только задание блокировки параметром тру - фолс. Я уже триггером запилил. Спасибо )
Вопрос: Как отключить блокировку таблицы MyISAM при UPDATE?

Или как вообще отключить навсегда все блокировки в MyISAM?
Ответ:
lagreen
ScareCrow,

фиксированной шириной таблицы или фиксированной длинной строки, простите


так это наоборот зло, которое твои любимые IOPs ы наоборот повышает...

Вопрос: Вопрос по временным таблицам.

Возник вопрос, что лучше использовать временную таблицу, либо реальную таблицу.
Задача такая, когда пользователь открывает документ то данные должны поступить в некую промежуточную таблицу. Если использовать ту же таблицу то придется использовать некий ID сессии чтобы различать открытые документы пользователей и при больших объемах данных изменения в документе будут более затратными.
Так вот, идеи такие:
1)входе в программу создать временную таблицу ## и в нее по мере необходимости помещать открытые документы. При выходе из программы сессия рвется и соответсвтенно данные удаляются.
2)создать 1 реальную таблицу на всех пользователей и туда помещать документы открытые. Там появится тогда номер сеанса чтобы каждый пользователь видел только свои документы. + Есть момент что если пользователь вышел из программы во время работы с документом то данные в таблице остануться и со временем там накопится куча ненужного хлама.
3) при входе в программу создавать таблицу например Docs+'ID сессии'. Пользователь работает в ней, а при выходе из программы то создать триггер который будет удалять данные таблицы.

Как считаете, какой метод более рационален?
Ответ:
Smoke999
А не получить кучу не нужной информации.

Если ваш уровень знаний низок, то это не значит, что информация ненужная.

Smoke999
Вроде здесь форум, где можно задать вопрос и получить какой-то ответ.

Вот вы и получили ответы. Если они вам не нравяться, то дело в вопросе наверное

Smoke999
я просто не понимаю зачем отвечать на вопросы которые не задают.

Потому что "Вроде здесь форум". Здесь ведут диалог, а не монолог.
Вопрос: OBI11. Вопрос по UID таблиц

Добрый день.
Подскажите плз ссылочки на доку, где можно узнать про UID объектов в репозитории?
Про GUIDам пользователей есть некоторая инфа, а вот таблицам, измерениям не нашел.

Конкретно интересует вопрос, что происходит с UID при копипасте объекта (например, таблицы) из RPD1 в RPD2?
UID сохраняется, меняется? Как это можно увидеть?
Может ли возникнуть пересечение/дублирование UID?
Ответ: dbi,
спасибо.
Да, судя по доке, UID уникальный всегда получается.

Кроме того ID тоже получается уникальный (и не повторяющий исходный ID), при переносе из RPD1 в RPD2.

Т.е. в вашем опыте, он получился одинаков, т.к. никаких других действий не было и, вероятно, он на обоих репозиториях просто сгенерился следующим по порядку числом.
Я в опытах пошел чуть дальше. И в RPD2 перед вставкой таблицы из RPD1, насоздавал еще объектов; т.о. счетчик ID поменялся, и в момент вставки таблицы был другим (большим по значению) чем в RPD1.

Так что пока вопрос для себя решил - буду считать, что все уникально и корректно при копипасте )

Насколько я понял equalize выравнивает UID и сливает объекты с разным UID в один.
Этого пока не требуется, главное знать, что нет дубликатов по ID.

"You can use the equalizerpds utility to equalize the Upgrade ID of objects in two separate repositories. If objects have the same Upgrade ID, they are considered to be the same object. The utility compares Upgrade IDs from the first repository (typically the original repository) with Upgrade IDs from the second repository (typically the modified repository). Then, the utility equalizes the Upgrade IDs of objects with the same name, using the Upgrade ID from the original repository."
Вопрос: Хорошо ли выключать блокировки уровня страница и таблица

Добрый день!

Есть следующая ситуация 2 таблицы, в них информация о данных загруженных пользователем, построчно.

Пользователь грузит разное кол-во данных. Старые данные удаляются. Проблема в том, что сейчас на этих таблицах довольно часты блокировки и вот, чтобы избежать блокировок в процедуре удаления стоит блок удаления 5000 записей (так не включается блокировка таблицы).
Так как иногда удаляется под 1 000 000, то по 5 тысяч данные удаляются небыстро. Хочется увеличить блок, но тогда будут блокировки.

Действия, которые я считаю верными:
- проверить фрагментацию индексов на таблицах, если больше 20% - делать ребилд (сейчас он совсем не делается)
- на всех индексах Allow page locks = False, ALTER TABLE SET ( LOCK_ESCALATION = DISABLE )
- увеличить блок до 50-100 тыс.

При этом я понимаю, что MS SQL сервер при обработке операций с большим количеством записей, будет есть больше ресурсов, с другой стороны данные действия должны снизить кол-во блокировок, так как записи обрабатываются разные - просто сейчас блокировки так как они на одной странице (на мой взгляд).

Основная претензия к этому решению со стороны DBA - отключение блокировок. Идея - нужно сделать так чтобы работало хорошо со стандартными настройками, через дизайн таблиц. Для этого первым полем в индексы включено поле, которое должно сделать данные более разреженными, но это все равно не помогает.

версия MS SQL Server 2012, snapshot isolation - off.

Напишите, пожалуйста, ваше мнение, за и против режима с отключенными постраничными блокировками и блокировками уровня таблица.
Ответ: aleks2,

нет, на большой несекционированной таблице все сразу медленнее, чем блоками, видимо как раз из-за блокировок, но все же. Короче здесь согласна лучше много маленьких транзакций, чем одна большая.

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

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

create table dbo.Counters
(
	CounterName varchar(20) not null,
	CounterValue int not null,
	constraint PK_Counters primary key clustered (CounterName)
)
insert into dbo.Counters values ('счет-фактура', 1)


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

Скорее всего тут подразумевается блокировка ячейки, но не факт. Подскажите пожалуйста.
Ответ: iap,

Стремный какой-то генератор. Особенно внешняя транзакция в функции.