MySQL record lock

12 отговора 327 прегледа
#1

MySQL record lock

Hi! Налага ми се да държа определен запис заключен за по-дълго време (извън отделна операция като UPDATE) и конструкции от сорта SELECT... FOR UPDATE и ... IN SHARED MODE не ми вършат работа (или аз не мога да ги подкарам - MySQL не е обичайната ми среда).
Споделете някои от любимите си техники, pls

Отговор
в отговор на bass #2

Re: MySQL record lock

Има оператор LOCK TABLES, повече за него туканка

дао дъ дзин

Отговор
в отговор на voyager #3

Re: MySQL record lock

Става въпрос за record-level lock - не мога да позволя на някой юзър да държи цялата таблица, докато направи каквото е почнал (в моя случай това може да продължи с часове).
Гледам из нета, че народът ползва контролни полета в таблицата, указващи дали записът се обработва от някого в момента (симулация на record lock), но не ми стои много елегантно...

Отговор
в отговор на bass #4

Re: MySQL record lock

Това заключване в MySQL го има при таблица InnoDB. Подвизава се под името "row-level locking". Виж в google-a за повече информацяия.
SELECT .. FOR UPDATE също го има в MySQL-а.

__________________________________
Пътят към ада е осеян с добри намерения
Отговор
в отговор на bass #5

Re: MySQL record lock

Няколко часа?

Не съм убеден, че каквото и да било заключване на ниво сървър е добра идея в твоя случай

Какъв е шанса докато един процес обработва този ред да се натрупа опашка от други процеси, които го чакат да се освободи и чакат с часове?

Забележи че това, което наричащ симулация на lock е по-гъвкавото решение защото можеш да провериш дали реда е заключен или не и да решиш дали изобщо да пуснеш заявка като го обработиш като събитие (Записа времменно не е достъпен моля изчакайте...изпиите две бири...откажете се за днес).

Ако разчиташ на сървъра той да ти приеме заявките и да се спасява може на ниво приложение да си създадеш доста повече ядове.

salle.online.bg/sig
Отговор
в отговор на salle #6

Re: MySQL record lock

4udq se ne e li dobra ideq v negoviq slu4ai da si napravi nqkakyv tip, podoben na semafor v samoto API, ot koeto izpolzva MySQL-a. Primerno "lock"-vaneto da stava v samoto php, makar 4e ne sm syvsem siguren kak 6te stane, pyk i v momenta nqmam vreme.

I want to walk into the lights

Отговор
в отговор на salle #7

Re: MySQL record lock

За протокола: пипам в MySQL през C++ Builder/dbExpress.
Иначе приложението се грижи да не пуска обработки към "заети" записи - въпросът е как да установява дали са заети. В документацията на първо четене не видях начин за проверка дали даден запис се обработва в момента...
Май все пак ще го направя с допълнително поле (или "семафор", както каза някой по-горе).
Тогава даже ще мога да кажа на късметлията, опитал да отвори "заключен" запис, кой го държи в момента.

Опа, забравих да кажа едно мерси :-)
Парафът на salle върху варианта с полето ми спестява няколко часа колебания :-\\

Редактирано от bass на

Отговор
в отговор на bass #8

Re: MySQL record lock

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

* 'семафор' lock 1|0 или y|n и т.н.
* lock_counter - ++, -- и съответно проверка >0

и така нататък .... нищо ново не казвам. със или без допълнителна информация.

Така дори можеш да въведеш Приоритети на Потребителите и да си организираш колкото си искаш сложна Опашка на заявките.

В крайна сметка опряхме до некои теоретични съображения от рода на това кое е работа на SQL сървъра и кое на Приложния сървър ... аз от известно време доказвам наляво и надясно, че примерно Транзакциите са задача от Приложното ниво, която обаче от години е вкарана в SQL сървърите.

М-у другото с какво си "закачаш" през Bulder-а? Надявам се не през ODBC?

salle.online.bg/sig
Отговор
в отговор на salle #9

Re: MySQL record lock

Не, ползвам libMySQL.DLL.
А по отношение на "семафора" - единственото, което ме притеснява ПО ПРИНЦИП, е вмъкването в таблицата на поле, нямащо нищо общо с данните (преди време тук май се дискутираше нормализиране на DB).
Едно време ми беше много удобно с X-BASE средите - като искаш да отвориш запис за писане, първо проверяваш дали е заключен. Ако не е - отваряш и заключваш. И ето как хем приложението се грижи за транзакциите, хем не се налагат акробатики по таблиците.

Отговор
в отговор на bass #10

Re: :)

Ако съвсем леко те перифразирам ще се получи дефиницията, че разликата м-у X-BASE и SQL сървърите е точно разликата между Файловите сървъри и Клиент-Сървър средата.

А това, че твоя проблем можеш и да може да го решиш с Транзакции води до съвсем същите въпроси за решаване:
Какво ще стане когато 10 'клиента' се опитат да направят commit с промени върху един и същи ред

Рано или късно установяваш, че спиш по спокойно когато си изпипаш нещата още в собствената си програма. Като на вълка дето му е дебел врата ....

salle.online.bg/sig
Отговор
в отговор на salle #11

А това?

:-)))
В процеса на лафа се сетих и за друга техника - като не искам във всеки запис да пазя допълнително паразитно (от гледна точка на данните) поле, да взема да организирам един регистър на "заключените" записи (една табличка с поле, съдържащо ключа на заключения запис, и евентуално ID на потребителя, който го ползва).
На пръв поглед е по-тромаво, но има следните предимства:
1. В основната таблица не се добавя поле (т.е., не се губи място, което на всичко отгоре нараства с всеки нов запис, а се използва временно);
2. Таблицата с "регистъра" съдържа незначително количество записи , не се увеличава безкрайно (съдържа данни само за текущо заключените записи);
3. Като резултат от 2, мога да видя дали даден запис е заключен в рамките на няколко десетки записа вместо в няколкостотин хиляди.

Мнение?

Редактирано от bass на

Отговор
в отговор на bass #12

Re: А това?

Остава да се погрижиш и за евентуален timeout на 'заключен ' запис или респективно активен ли е аджеба тоз потребител или нещо някъде е гръмнало и е забравило да освободи записа

Изобщо ако добавиш един timestamp ще знаеш и от колко време насам се мотляви процеса.

Такава таблица обаче направо си плаче за TYPE=HEAP

Още един малък трик когато се притесняваш (и правилно) за всеки байт в таблицата.

CREATE .... lck CHAR(0) DEFAULT NULL ... ;

Това е най-тънката възможна дефиниция, която все още е използваема. Трикът е, че за колонка която може да е NULL се добавя само 1 bit.

Това което получаваш със CHAR(0) и колонка която може да бъде или '' (с дължина 0 естествено) или NULL

Е да това си е Хакерска техника, но я имай предвид




salle.online.bg/sig
Отговор
в отговор на salle #13

Re: А това?

Дааа, тая техника я срещнах в нета докато се чудех къде са му логическите полета на MySQL :-))))) С нея си става като по книга - 1 бит за true или false (вместо цял enumeration (yes, no) ), но това излезе извън главната тема...
Иначе нещата се избистриха, сега отивам да копам на Buildera :-\\
Пак 10x!

Отговор