2017-02-21 11 views
0

Я хочу, чтобы гарантировать, что один работник имеет ровно один менеджерКакая подходящая технология блокировки для предотвращения ввода данных? [PostgreSQL]

CREATE TABLE IF NOT EXISTS user_relationships (
    object_id SERIAL PRIMARY KEY    NOT NULL UNIQUE, 
    manager_id INT REFERENCES users (object_id) NOT NULL, 
    worker_id INT REFERENCES users (object_id) NOT NULL, 
    CHECK (manager_id != worker_id), 
    UNIQUE (manager_id, worker_id) 
); 

У меня есть ряд заявлений SQL, используя Read Committed уровень изоляции транзакций,

BEGIN 
SELECT * FROM users WHERE id=manager_id AND acc_type="manager" FOR UPDATE; 
SELECT * FROM users WHERE id=worker_id AND acc_type="worker" FOR UPDATE; 
SELECT * FROM relationships WHERE id=worker; 
INSERT INTO relationships (m, w) VALUES (manager_id, worker_id) 
COMMIT 
  • Я выяснил первые два ДЛЯ ОБНОВЛЕНИЯ для предотвращения одновременной транзакции s от изменения типа учетной записи пользователя mid transaction
  • Я не мог понять, какой «трюк» использовать для третьего запроса. Третий запрос должен возвращать пустой список, чтобы гарантировать, что работник еще не принадлежит любому менеджеру.
  • Третий запрос ДЛЯ ОБНОВЛЕНИЯ не работает, потому что я ожидаю пустую строку.
  • Из-за третьего запроса я запускаю риск одновременной транзакции, добавляя дубликата рабочего к разным менеджерам.

Что можно сделать для принуждения одного работника к одному менеджеру?

+0

@VaoTsun '(1,2)' и '(2,2)' будет считаться неидеальным, но у рабочего 2 будет два менеджера, что Zanko пытается предотвратить сейчас –

+0

IC. Если бы этого object_id не было, уникальные (manager_id) и unique (worker_id) могли бы сделать трюк? –

ответ

2

Возможно, вам нужно добавить к UNIQUE тягот к worker_id:

CREATE TABLE IF NOT EXISTS user_relationships (
    object_id SERIAL PRIMARY KEY    NOT NULL UNIQUE, 
    manager_id INT REFERENCES users (object_id) NOT NULL, 
    worker_id INT REFERENCES users (object_id) UNIQUE NOT NULL, 
    CHECK (manager_id != worker_id) 
); 

Но лучше добавить поле manager_id INT REFERENCES users (object_id) NOT NULL в таблице users и не используйте user_relationships.

+0

Спасибо! Я не видел такого простого решения! – Zanko

 Смежные вопросы

  • Нет связанных вопросов^_^