SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 16.08.2008 20:51:51

dead
Участник
Зарегистрирован: 16.08.2008
Сообщений: 14

Эмуляция транзакции

mysql 5.0.

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

В простейшем случае все делается в 2 этапа:
1) Проверяется, что количество единиц оборудования с данным типом равно нулю
2) если условие 1 выполняется - осуществляем удаление

Однако, маловероятна, но возможна ситуация, когда между действиями 1 и 2 параллельно кто-то не создаст оборудование с целевым типом. Поэтому заходелось оформить все одним запросом (транзакциям mysql пока не доверяю, это пока не обсуэждаем).

Придумал и проверил (работает) запрос:

DELETE FROM eqtype WHERE type=(SELECT IF(COUNT(type)>0,0,5) FROM equip WHERE type=5)

- удаляет тип оборудования № 5

Вопрос. Не слишком я нахитрил и не заметил простых способов решения данной проблемы?

Неактивен

 

#2 16.08.2008 22:02:15

dead
Участник
Зарегистрирован: 16.08.2008
Сообщений: 14

Re: Эмуляция транзакции

Нашел нормальный вариант:

DELETE FROM eqtype WHERE type NOT IN (SELECT type FROM equip WHERE type=5) AND type=5

smile

Неактивен

 

#3 17.08.2008 02:02:27

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Эмуляция транзакции

DELETE FROM eqtype WHERE NOT EXISTS (SELECT equip.type FROM equip WHERE equip.type=eqtype.type);


Напрасно не доверяете транзакциям.

Неактивен

 

#4 17.08.2008 02:21:19

dead
Участник
Зарегистрирован: 16.08.2008
Сообщений: 14

Re: Эмуляция транзакции

не доверяю, потому что эта фича новая в мускуле, а детальной инфы по ней нет. Меня интересует поведение в критических ситуациях. Пример из другой области чтоб было понятней, что меня волнует: допустим залочил я таблицу, вдруг мой скрипт "вылетает", ну мало ли что случилось, что в этом случае будет? таблица так и останется залоченной? на сколько? Меня просто интересуют такие тонкости, критических ситуаций я повидал, взять хотя бы бока с соединениями когда не работает днс, теперь на всех серверах в конфигах мускула резолв отключаю.

За запрос спасибо, так и знал что есть красивые решения

P.S. Не совсем то - мне нужно чтоб не все удалялось, а только тот type, который я указал. Но это неважно, ваш запрос направил на вариант решения

Отредактированно dead (17.08.2008 02:24:53)

Неактивен

 

#5 17.08.2008 02:53:14

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Эмуляция транзакции

Резолв это известная проблема, можно его отключить, а можно прописать хост в /etc/hosts

Транзакции в MySQL допустимы при использовании движка InnoDB. Блокировки в транзакциях работают в зависимости от уровня изоляции. Следует учитывать возможность провала транзакции, то есть на запрос COMMIT можно ждать ошибки (если кто-то другой изменил эти данные и уже завершил транзакцию), в случае такой ошибки, транзакция откатывается.

Если скрипт вылетает, то соединение разрывается и MySQL должен откатить транзакцию. Хуже, если скрипт виснет, продолжая работу.

http://dev.mysql.com/doc/refman/5.1/en/ … ation.html

Неактивен

 

#6 17.08.2008 02:58:01

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Эмуляция транзакции

В Вашем примере, запрос SELECT в транзакции не запретит никому извенять таблицу. Следующий за ним апдейт выполнится, как это было бы вне транзакции (если таблицу не блокируют другие). При выполнении COMMIT, если данные, выбранные с помощью SELECT не были изменены другими транзакциями, транзакция завершит запись, в противном случае откатится. Я привел общее описание, конкретное поведение зависит от уровня изоляции - попробуйте с разными уровнями повыполнять параллельные транзакции.

Неактивен

 

#7 17.08.2008 04:50:01

dead
Участник
Зарегистрирован: 16.08.2008
Сообщений: 14

Re: Эмуляция транзакции

Я правильно понял, что сложный запрос с подзапросом НЕ обязательно выполняется как цельная операция?

Неактивен

 

#8 17.08.2008 11:49:28

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Эмуляция транзакции

Цельная операция - это запись одного слова в одну ячейку памяти. Все остальные операции - составные. Если это запрос с подзапросом, то происходит логически следующее
LOCK TABLES a READ, b WRITE;
// Цикл (если требуется)
SELECT FROM a ...;
DELETE FROM b ..;
// Конец цикла
UNLOCK TABLES;

Innodb лучше тем, что блокируются не таблицы целиком, а только определенные задействованные строки (row-based locking), но это только в том случае, если возможно легко определить какие именно строки задействованы. В случае подзапроса определить это во многих случаях не удастся до исполнения запроса (и заблокируется вся таблица), а в случае двух отдельных запросов, второй будет уже конкретным SELECT FROM b WHERE id=303 и блокировка будет наложена только на строку с id=303. Это причина, почему несколько запросов часто (но не всегда) быстрее использования подзапросов.

http://dev.mysql.com/doc/refman/5.0/en/ … cking.html

Неактивен

 

#9 17.08.2008 14:44:04

dead
Участник
Зарегистрирован: 16.08.2008
Сообщений: 14

Re: Эмуляция транзакции

Да, есть над чем задуматься мне... Я как раз выбирал myisam из-за больших требований к производительности чем к надежности, но смотрю все зависит от характера использования. Вероятно прийдется делать сравнительные характеристики в бою.

Чтобы не создавать новую тему, задам еще один вопрос. Есть 2 базы на разных серверах. Необходимо сделать запрос с join из таблиц в разных базах. Я так понимаю штатными средствами это сделать нельзя? Т.е. только перекидывать таблицу в другую базу?

Спасибо за ответы

Неактивен

 

#10 17.08.2008 15:01:59

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Эмуляция транзакции

В случае, если SELECT доминирует над UPDATE/INSERT, MyISAM лидирует по производительности. Если вставки/обновления происходят часто, одновременно с выборками, то InnoDB быстрее из-за построчной блокировки (фактичести запросы не блокируют один другой).

Требования мультиверсионности делают хранилище Innodb сложнее, чем MyISAM. Кроме того, для MyISAM работает кэш индексов http://sqlinfo.ru/articles/info/3.html а для innodb и индексы и данных кэшируются в общем кэше (Параметр: innodb_buffer_pool_size)

Можно использовать FEDERATED http://dev.mysql.com/doc/refman/5.1/en/ … ngine.html
Но: про транзакции здесь можно забыть, с производительностью надо также быть аккуратным (во многих случаях FEDERATED-таблица для выполнения запроса вынуждена выбрать всю таблицу целиком с удаленного сервера).

Неактивен

 

#11 18.08.2008 03:57:46

dead
Участник
Зарегистрирован: 16.08.2008
Сообщений: 14

Re: Эмуляция транзакции

Благодарю за ответы

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson