Атомное ведение счетчика с использованием Subsonicic ActiveRecord - PullRequest
0 голосов
/ 12 мая 2010

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

У меня есть таблица компаний и таблица вакансий. Я хочу, чтобы у каждой компании был свой набор job_numbers. У меня есть автоинкремент job_id, но эти цифры являются общими для всех компаний. то есть: номера должностей обычно должны увеличиваться без пробелов для каждой компании.

т.е.:

  • компаний (company_id, next_job_number)
  • рабочих мест (company_id, job_id, job_number)

В настоящее время я делаю это (как метод в классе частичной работы):

public void SaveJob()
{
    using (var scope = new System.Transactions.TransactionScope())
    {
        if (job_id == 0)
        {
            _db.Update<company>()
                .SetExpression("next_job_number").EqualTo("next_job_number+1")
                .Where<company>(x => x.company_id == company_id)
                .Execute();

            company c = _db.companies.SingleOrDefault(x => x.company_id == company_id);

            job_number = c.next_job_number;
        }

        // Save the job
        this.Save();

        scope.Complete();
    }
}

Кажется, это работает, но я не уверен, что здесь есть подводные камни? Это просто неправильно, но я не уверен, как еще это сделать.

Любой совет приветствуется.

Ответы [ 2 ]

1 голос
/ 13 мая 2010

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

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

"LAST_ORDER_NUMBER_COMPANY_" + company_id

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

1 голос
/ 13 мая 2010

Во-первых,

вам следует использовать TransactionScope вместе с SharedDbConnectionScope, иначе ваша транзакция не будет работать должным образом.

Во-вторых,

Я бы использовал другой подход с одним утверждением и без необходимости сохранять job_id в компании)

  1. Сохранить запись с помощью job_number = 0

  2. Обновить запись чем-то вроде этого

    ОБНОВЛЕНИЕ ЗАДАНИЙ УСТАНОВИТЬ JOB_NUMBER = (ВЫБЕРИТЕ МАКС (номер задания) +1 ОТ РАБОТЫ, ГДЕ company_id = 12345) ГДЕ job_id = "+ this.job_id;

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

...