2013-08-24 4 views
1

Предположим, у меня есть приложение, основанное на таблице пользователей SQL, и вы хотите избежать нескольких пользователей с тем же именем:SQL-условные вставки и другие множественные запросы, выполненные в порядке атома/все или ничего/не чередующиеся.

Когда я вставляю нового пользователя в свою таблицу, я должен убедиться, что уже нет похожих строк. Так что 2 запросов, второй только происходит, если первый один не дал ничего:

-query1: select * from users where username='Marie-Antoinette' 
-query2: insert into users ('','Marie-Antoinette','37')    

Несколько приложений экземпляров доступ к общей базе данных одновременно, как я могу убедиться, что ни один из запросов не вставлена ​​между Query1 и Query2? Что это делается как атомная операция в БД без ничего между ними?


Там может быть способом, синтаксис сделать условные вставки, но мой вопрос больше о "как убедиться, что я могу сделать N запросы с гарантией, что никаких запросов от других клиентов будут чередоваться в моем партия "?

Скажем, у меня есть, в моем приложении, операция, требующая 4 запросов:

моя работа состоит из:

-query1: insert stuff in table 1 
-query2: select stuff from table 2 
-query3: insert stuff in table 3 
-query4: update stuff in table 4 

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

в течение долгого времени, это было бы:

-client #1 query 1 
-client #1 query 2 
-client #1 query 3 
-client #1 query 4 

-client #2 query 1 
-client #2 query 2 
-client #2 query 3 
-client #2 query 4 

-client #1 query 1 
-client #1 query 2 
-client #1 query 3 
-client #1 query 4 

Каков рекомендуемый подход для достижения этой цели?

ответ

2

Рекомендуемый подход заключается в добавлении уникального индекса (или что то же самое уникальное ограничение) на столе так, имеющих одинаковые имена пользователей не будет работать на вставке:

create unique index users_username on users(username); 
+0

Can быть сложным для обработки правильного исключения без обращения к другим.Я предпочитаю не производить ошибок вообще, проверяя право. – usr

1

После дальнейших исследований, кажется, я должен использовать «транзакции», которые должны иметь все свойства «ACID» (для второй части моего вопроса - общий случай).

http://en.wikipedia.org/wiki/Database_transaction

http://en.wikipedia.org/wiki/ACID

Однако использование транзакций в одиночку не дает мне все гарантии, что я упомянул в моих вопросах. Гарантия «Изоляция», в частности, может быть проблематичной.

http://en.wikipedia.org/wiki/Isolation_(database_systems)

SQL базы данных имеют свойство "Уровень изоляции транзакций", который может быть проверен и должен быть установлен на "Serializable"

, например, в моей базе данных MySQL:

SELECT @@global.tx_isolation; 

>> REPEATABLE-READ 

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE 

>> OK 

SELECT @@global.tx_isolation; 

>> SERIALIZABLE