|
неудобный constraint -- как обеспечить?
|
|||
---|---|---|---|
#18+
Ситуация -- есть теблица (А), ссылающаяся на другую (Б), причем есть бизнес-условие, что число записей в Б, которые привязаны к одной записи в А, должно быть не больше, чем указано в одном из аттрибутов А. Чтобы было понятнее: в реальном мире А -- это некая кормушка, имеющая N сосок. Аггрегаты Б ищут себе кормушку, и, найдя, цепляются к соске. Разумеется, к А не может быть прицеплено больше Б-шек, чем есть сосок у А. Число сосок у А от 2 до бесконечности, но практически -- не более 64. Проблема в том, что Б ищут себе свободную кормушку в параллельных транзакциях -- "смотрим количество свободных сосок, если более 0, то присасываемся". При этом может возникнуть ситуация, когда число Б станет больше числа сосок у экземпляра А, от чего либо А, либо Б сломается. :( Сейчас это обойдено на уровне приложения -- создан специальный объект, вход куда синхронизирован, там коммитится текущая транзакция (чтобы иметь свежие данные), проверяется, добавляется, опять коммитится. Вроде бы, имеем гарантию, что все пойдет как надо, но ... некрасиво это очень. Во-первых, коммит транзакции (а мало ли чего до этого было измененено -- надо помнить, что перед подцеплением ничего менять нельзя). Во-вторых, синхронная секция снижает производительность. Возникла мысль, что чем-то могут помочь триггера. Но, насколько я понимаю, триггера точно так же пашут внутри транзакции, и узнать, что в параллельной транзакции уже присосались -- не может. Или я неправ? Мысли, идеи? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.08.2003, 14:39 |
|
неудобный constraint -- как обеспечить?
|
|||
---|---|---|---|
#18+
Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.09.2003, 09:57 |
|
неудобный constraint -- как обеспечить?
|
|||
---|---|---|---|
#18+
BEGIN; SELECT * from table_a where table_a.maxlink - (SELECT count(*) from table_b where table_a.link_down = table_b.link_up) > 0 FOR UPDATE ; INSERT into table_b (link_up) VALUES ( то значение link_down из таблицы table_a, которое мы получили в предыдущем запросе ); COMMIT; Смысл в том, что параллельный процесс на этом же куске зависнет на этом самом FOR UPDATE. И будет висеть до тех пор пока ты не сделаешь COMMIT ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2003, 17:27 |
|
неудобный constraint -- как обеспечить?
|
|||
---|---|---|---|
#18+
Спасибо за наводку . Действительно в селекте есть возможность прописать: [ FOR UPDATE [ OF update_table [, ...] ] ] где: /* FOR UPDATE The locking clause that places an implicit ROW SHARE MODE lock (see LOCK") on the from_item table selected in the current transaction. OF update_table A specific table to which to apply ROW SHARE MODE locking when multiple tables are selected in the FROM clause. */ ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2003, 18:31 |
|
|
start [/forum/search_topic.php?author=loopback&author_mode=last_topics&do_search=1]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
get settings: |
10ms |
get forum list: |
13ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
29ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
others: | 29813ms |
total: | 29983ms |
0 / 0 |