транзакции базы данных и потоки - PullRequest
0 голосов
/ 14 июня 2009

У меня есть функции lock (), unlock (), query1 (), query2 () и query3 (). Функции запросов просто выполняют какой-либо запрос к базе данных и могут рассматриваться как доступ к ней. Они не блокируются. Моя система многопоточная.

Мне нужна следующая функция: если lock () вызывается из потока p1, будут выполняться только запросы из потока p1, а запросы из всех других потоков ожидают разблокировки. Как мне это сделать?

Я использую pthreads из C. Для этого поток должен знать, что он удерживает блокировку. Но у pthreads такой функции нет.

Это неправильный дизайн ??

EDIT:

Function1(){
lock();
query1();
query2();
doQuery3();
unlock();
}

doQuery3(){
lock();
query3();
unlock();
}

Я хочу использовать функцию lock (), если поток уже удерживает эту блокировку, он не должен ждать блокировки. Это должно просто бежать. Дело в том, что моя функция lock () фактически запускает транзакцию. Я хочу запустить кучу вещей в сделке. И unlock () завершает транзакцию. Я хочу иметь возможность цепочки запросов. Одним из обходных путей является вызов метода query3 () в Function1 () вместо doQuery3 (); Это означало бы, что для каждой функции есть две версии, одна с блокировкой и одна ванильный запрос ()

Опять же, эти функции блокировки и разблокировки могут быть или не быть мьютекс-блокировками. Я пытался реализовать его с помощью pthread mutex, но не смог. Потому что pthread_mutex_lock в одном и том же потоке блокирует! Какие-нибудь крутые трюки ??

Ответы [ 4 ]

2 голосов
/ 14 июня 2009

Да, ваш дизайн не так.

Блокировка должна осуществляться в базе данных.

1 голос
/ 14 июня 2009

Я не уверен, что понял ваш вопрос / дизайн, однако ...

Мне нужна следующая функция: если lock () вызывается из потока p1, будут выполняться только запросы из потока p1, а запросы из всех других потоков ожидают разблокировки. Как мне это сделать?

Если единица работы, вызываемая потоком p1, выглядит следующим образом ...

void doQuery1()
{
  //get the lock
  //if someone else has the lock, block until it's released
  lock();

  //now we have the lock
  //do query
  query1();

  //our work is done
  //release the lock, let another thread run
  unlock();
}

... и работа, вызываемая другими потоками, похожа ...

void doQuery2()
{
  lock();
  query2();
  unlock();
}

void doQuery3()
{
  lock();
  query3();
  unlock();
}

... тогда, если p1 имеет блокировку, то, поскольку другие потоки также всегда вызывают функцию блокировки, прежде чем они пытаются выполнить запрос, и поскольку функция блокировки ожидает разблокировки, тогда я думаю, что это ответ на ваш вопрос: в том, что запросы из других потоков будут ожидать разблокировки (т. е. потому что все потоки всегда вызывают блокировку, и потому что блокировка ожидает разблокировки).

0 голосов
/ 14 июня 2009
  • Если ваша база данных обрабатывает блокировки, напр. База данных SQL, тогда транзакция начинается явно или с первого SQL-оператора и заканчивается при выполнении коммита. Вы должны только синхронизировать (например, используя очередь) вашу программу, если вы используете общие данные.

  • Если ваша база данных не обрабатывает блокировки, то блокировки следует использовать как:

    START_TRANSACTION = pthread_mutex_lock

    END_TRANSACTION = pthread_mutex_unlock

но нет обработки отката и защиты от несоответствия.

0 голосов
/ 14 июня 2009

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

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
pthread_mutex_lock(&mutex);
queryN(); // critical section
pthread_mutex_unlock(&mutex);

Если доступ к базе данных осуществляется только из вашей единственной программы, она будет работать для вас. Я думаю, что если ваши запросы выполняют r / w, ваша база данных будет в любом случае блокировать таблицы / строки в зависимости от ситуации.

Если все ваши запросы окружены блокировкой и разблокировкой, вы достигнете желаемого.

...