powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Задача для версионника
123 сообщений из 123, показаны все 5 страниц
Задача для версионника
    #32826305
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Представим себе вокзал. Несколько окошек, где продают билеты. Каждая транзакция - продажа партии билетов.
Как проходит этот процесс мы все знаем. Подходим к окошку и говорим - мне 2 билета до Москвы. И начинается... транзакция. Заканчивается она лишь тогда, когда внесены все паспортные данные и деньги за билеты получены.
а теперь, предположим что вы - отправляете в Москву группу туристов. Скажем так - человек 30...Т.е. я хочу сказать что транзакция может получиться очень длинной. А билеты - ресурс ограниченный. Может не хватить. Слеловательно билеты для группы должны быть заблокированы в начале транзакции. Подобные задачи возникают довольно часто. Например при продаже акций или в процессе набивки накладной
Задача:
1) Продажа проходит одной транзакцией
2) Продажа (транзакция) растянута во времени (до получаса)
3) продавать билеты на один и тот же рейс могут одновременно из нескольких окошек.

Для блокировочника - все понятно, решить задачу очень легко.
А как будет выглядеть решение для версионника? т.е. я имею в виду Оракл?
...
Рейтинг: 0 / 0
Задача для версионника
    #32826335
zass
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Организуйте топик для ОРАКЛА, так быстрее будет
...
Рейтинг: 0 / 0
Задача для версионника
    #32826351
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanА как будет выглядеть решение для версионника? т.е. я имею в виду Оракл?
На Оракле это сделать невозможно!!!
Написал бы структуру БД. Билеты ведь не только по количеству учитываются, но и по местам. Например можно быстро "застолбить" нужные места в нужном количестве признаком "зарезервировано". После ввода всей инфы - поменять статус на "продано".
...
Рейтинг: 0 / 0
Задача для версионника
    #32826358
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
select for update..?
...
Рейтинг: 0 / 0
Задача для версионника
    #32826373
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Серега
Разве Оракл не лучшая СУБД для ОЛТП задач?
День длинный, может кто-нить, чё-нить и предложит, а мы посмотрим ...
...
Рейтинг: 0 / 0
Задача для версионника
    #32826408
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanДень длинный, может кто-нить, чё-нить и предложит, а мы посмотрим ...
Я тебе через 20 минут предложил, чем не ндравится?
...
Рейтинг: 0 / 0
Задача для версионника
    #32826418
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
СерегаЯ тебе через 20 минут предложил, чем не ндравится?
Это не решение а отмазка..
...
Рейтинг: 0 / 0
Задача для версионника
    #32826425
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Слишком сильно усложнять задачу не будем начнем с этого:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
-----------------------------------------------------------------------
--  Расписание движения поездов
-----------------------------------------------------------------------
--  route_num       рейс
--  departure_dt    дата отправления
--  ticket_cnt      количество билетов (всего)
--  ticket_sold     количество проданных билетов
--
create table routes (
    route_num       char( 5 ) not null,
    departure_dt    date not null,
    tickets_cnt     integer not null,
    tickets_sold    integer,
    constraint AtCnt
        check((tickets_cnt>=tickets_sold) or (tickets_sold is null)),
    constraint AtRoute_PK
        primary key (route_num,departure_dt)
)
@
...
Рейтинг: 0 / 0
Задача для версионника
    #32826456
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanСлишком сильно усложнять задачу не будем начнем с этого:

ИМХО, твоя таблица больше смахивает на отмазку, чем мое предложение.
Продай мне по твоей структуре 5 общих, 3 плацкартных, 2 купейных и 1 СВ билет. Тут и Оракл сдохнет наверное.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826460
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 gardenman
Тебе если для диплома - тогда за бабло надо бы, за так голову ломать над красивыми решениями неохота никому.

А если для того, чтобы работало - то Серега тебе уже предложил единественное правильное решение. Причем и для MS SQL и для Оракла.

И еще подсказка - транзакции тут ни при чем. Если конечно нужно самое уродское решение - тогда используй транзакции, вешай всю систему.

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32826479
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Серега gardenmanСлишком сильно усложнять задачу не будем начнем с этого:

ИМХО, твоя таблица больше смахивает на отмазку, чем мое предложение.
Продай мне по твоей структуре 5 общих, 3 плацкартных, 2 купейных и 1 СВ билет. Тут и Оракл сдохнет наверное.

Нет, это не отмазка...поверь, решение есть. Не хочешь торговать билетами?...
Давай тогда торговать акциями. Обыкновенными неименными привелигированными. Можно поработать на складе. Предположим у нас есть 100 ящиков какого-то товара. И в разных филиалах его продают. сначала - оформление документов (выписка фсяких накладных и пр...). И чтоб пока документы оформляются - наши ящики не ушли кому-нить другому. Все - одной транзакцией.
В общем - условия - те же...
...
Рейтинг: 0 / 0
Задача для версионника
    #32826485
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tygra2 gardenman
Тебе если для диплома - тогда за бабло надо бы, за так голову ломать над красивыми решениями неохота никому.

А если для того, чтобы работало - то Серега тебе уже предложил единественное правильное решение. Причем и для MS SQL и для Оракла.

И еще подсказка - транзакции тут ни при чем. Если конечно нужно самое уродское решение - тогда используй транзакции, вешай всю систему.

-- Tygra's --

Я свой диплом получил в 1988 году....((( Вообще-то тогда еще этому не учили.
А сейчас столько много умных, после интститутов....
...
Рейтинг: 0 / 0
Задача для версионника
    #32826508
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЯ свой диплом получил в 1988 году....((( Вообще-то тогда еще этому не учили.
А сейчас столько много умных, после интститутов....
Там и сейчас этому не учат :) Так что не переживайте - все в одинаковой ситуации, хоть сейчас, хоть тогда, хоть с дипломом, хоть без.

А с терминами все-же не заморачивайтесь - делайте так, как удобно, как лучше. Главное чтобы работало. И не важно, как оно там называется и кем кому приходится :)

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32826544
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanНет, это не отмазка...поверь, решение есть. Не хочешь торговать билетами?...
Давай тогда торговать акциями.В общем - условия - те же...
Фиг тебе - те-же? Отсюда и проблема у тебя растет. 8-) Даже в торговле ящиками товара есть варианты.

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

Исходи из того, что если ящики кончаются - это плохо (недоработка снабженцев), и скорее всего будет встречаться не очень часто. Далее. С чего ты решил что твое общение с БД заканчивается с концом транзакции? Отнють. Если транзакция прошла, то да. А если произошла искл.ситуация (поставь например ограничение на количество>=0 и ты ее получишь) и произошел откат, то никто не запрещает тебе в программе выяснить причину отката (опросить "свежее" количество), дать исправить документ юзеру и попытаться сохранить снова. Или, на худой конец, вывести юзеру месадж - "Извини, братан, кто первый встал того и тапки".
И тут кстати вообще по барабану, ИМХО, версионник или блокировочник. Нюансы могут быть, но общая схема та-же.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826545
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дорогой Tygra! Смысл того, что здесь написано совсем другой. И я имел в виду совсем не то, о чем ты подумал. Я хочу сказать что существует класс задач, для которых Оракл не катит .
Вот как ты думаешь, почему кластерные реализации от Оракла и от IBM такие разные? Ведь совсем не потому, что Оракл круче и совсем не потому, что IBM не могут как Оракл. А потому, что в силу своих архитектурных особенностей JОракл по-другому просто не может )
...
Рейтинг: 0 / 0
Задача для версионника
    #32826553
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Серега
Вот-вот.... если мы не можем это запрограммировать, то давайте изменим процесс так, чтобы это можно было сделать... Хороший способ решать вопросы...делать вид, какбудто их нет...(С) Макаревич
...
Рейтинг: 0 / 0
Задача для версионника
    #32826555
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanСмысл того, что здесь написано совсем другой. И я имел в виду совсем не то, о чем ты подумал. Я хочу сказать что существует класс задач, для которых Оракл не катит .
Конечно!!! Но практически все задачи связанные с БД, не входят в этот перечень.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826559
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanВот-вот.... если мы не можем это запрограммировать, то давайте изменим процесс так, чтобы это можно было сделать...
Переведи.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826722
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эта задача как раз из тех, для которой катят все СУБД, у которых есть транзакции. Можно и совсем без транзакций, но это несерьезно будет :)

Так что вас так смутило то в задаче?
Вам предложено решение. Вы толи его не принимаете, толи еще что- напишите, в чем проблемы.
Вами пока не предложено ни одного решения.

Кстати, с ящиками та же беда - не надо тут никаких транзакций, транзакции с клиента - это зло!

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32826763
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имеется запись
insert into routes
(route_num,departure_dt,tickets_cnt,tickets_sold)
values ('C100','31.12.2004',1000,950)


видно, что было 1000 билетов, 950 из которых - продано.=> осталось 50 билетов.
Иммется два окошка. К первому подходит гражданин, и пытается 2 купить билета.
Кассарша начинает транзакцию, говорит:
select ... for update. Запись - блокирована.
К другому окошку подходит другой мэн...и просит 2 билета на тот же рейс.
Ну и другая кассирша тоже делает select ... for update на ту же запись...
ну и как им быть? Ждать пока кассирша в первом окошке не расчитается с клиентом и не сделает commit?
...
Рейтинг: 0 / 0
Задача для версионника
    #32826774
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторвидно, что было 1000 билетов, 950 из которых - продано.=> осталось 50 билетов.
Иммется два окошка. К первому подходит гражданин, и пытается 2 купить билета.
Кассарша начинает транзакцию, говорит:
select ... for update. Запись - блокирована.
К другому окошку подходит другой мэн...и просит 2 билета на тот же рейс.
Ну и другая кассирша тоже делает select ... for update на ту же запись...
ну и как им быть? Ждать пока кассирша в первом окошке не расчитается с клиентом и не сделает commit?
Вам уже сказали решение без транзакций - именно то, которое нужно. Что вы к транзакциям прицепились?

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32826776
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если у вас уже есть та структура, которую вы приводите, и менять ничего нельзя - тогда решения нет, пусть все пассажиры ждут, пока первый кассир в тувалет сходит и освободит таблицу :))

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32826778
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 tygra
Пожалуйста, не заходи в этот топик, кругом столько других интересных...
...
Рейтинг: 0 / 0
Задача для версионника
    #32826800
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman Ждать пока кассирша в первом окошке не расчитается с клиентом и не сделает commit?
А, при такой схеме , зачем блокировать вообще, если у нас еще 50 билетов, а берут обычно не более 5? А если бы было 950 свободных и очередища? Наверное поезд уедет прежде, чем один вагон обилетят.

gardenmanНет, это не отмазка...поверь, решение есть.
Ну не томи уже, опубликуй.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826801
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Продолжаем....
Усложним задачу... пусть все будет без транзакций...
К первому окошку подходит руководитель тургруппы - и заказывает 30 билетов... Ну и естественно начинает оформлять их по очереди...
Пока они то да се...по одному билету оформляли, на других вокзалах и в других окошках скупили 25 билетов.. ну и 5 билетов руководителю тургруппы не хватило... Обидно...А нужно туристов скопом везти.... Придется сдавать купленные.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826815
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решение:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
connect to test@

-----------------------------------------------------------------------
--  Расписание движения поездов
-----------------------------------------------------------------------
--  route_num       рейс
--  departure_dt    дата отправления
--  ticket_cnt      количество билетов (всего)
--  ticket_sold     количество проданных билетов
--
create table routes (
    route_num       char( 5 ) not null,
    departure_dt    date not null,
    tickets_cnt     integer not null,
    tickets_sold    integer,
    constraint AtCnt
        check((tickets_cnt>=tickets_sold) or (tickets_sold is null)),
    constraint AtRoute_PK
        primary key (route_num,departure_dt)
)
@

-----------------------------------------------------------------------
--  Проданные билеты
-----------------------------------------------------------------------
--  route_num       рейс
--  departure_dt    дата отправления
--  tickets_sold    количество проданых билетов
--  desk            номер кассы
--  ts              дата продажи
create table sales (
    route_num       char( 5 ) not null,
    departure_dt    date not null,
    tickets_sold    integer check (tickets_sold> 0 ),
    desk            integer not null,
    ts              timestamp,
    constraint AtRoute_FK foreign key (route_num,departure_dt)
        references routes (route_num,departure_dt) on delete restrict
)
@

create index ISaleDesk
    on sales (desk,ts) allow reverse scans
@

create unique index ISaleRoutes
    on sales (route_num,departure_dt,desk,ts) allow reverse scans
@

---------------------------------------------------------------------
--  Блокировки на билеты
---------------------------------------------------------------------
--  route_num       char(5) not null,
--  departure_dt    date not null,
--  ticket_lock     integer check (ticket_sold>0),
--  desk            integer
create table locks (
    route_num       char( 5 ) not null,
    departure_dt    date not null,
    tickets_lock    integer check (tickets_lock> 0 ),
    desk            integer,
    constraint AtRouteI_FK foreign key (route_num,departure_dt)
        references routes (route_num,departure_dt) on delete restrict
)
@
create unique index ILock
    on locks (route_num,departure_dt,desk) allow reverse scans
@
create unique index ILockDesk
    on locks (desk,route_num,departure_dt) allow reverse scans
@

echo ---------------------------@
echo Заливаем расписание поездов@    
echo ---------------------------@
@
insert into routes
    (route_num,departure_dt,tickets_cnt,tickets_sold)
values
    ('C100',date('25.12.2004'), 1000 , 0 ),
    ('C100',date('26.12.2004'), 1000 , 0 ),
    ('C100',date('27.12.2004'), 1000 , 0 ),
    ('C100',date('28.12.2004'), 1000 , 0 ),
    ('C100',date('29.12.2004'), 1000 , 0 ),
    ('C100',date('30.12.2004'), 1000 , 0 ),
    ('C100',date('31.12.2004'), 1000 , 0 )
@
commit@

select * from routes@

--------------------------------------------------------------
-- Триггер, проверяющий, что есть еще незаблокированные билеты
-- которые можно продать или заблокировать для продажи
--------------------------------------------------------------
create trigger BILocks 
no cascade before insert on locks
referencing new as N
for each row
when
(
    N.tickets_lock
    >
    (select
        routes.tickets_cnt-routes.tickets_sold-
        coalesce((
            select sum(tickets_lock) from locks
                where locks.route_num=N.route_num
                        and locks.departure_dt=N.departure_dt
        ), 0 )
    from
        routes
    where
        routes.route_num=N.route_num
        and routes.departure_dt=N.departure_dt
    )
)
    signal sqlstate '75001' set message_text='Too many tickets'
@
commit@

------------------------------------------------------------
-- Продаем именно столько билетов, сколько заблокировали
------------------------------------------------------------
create trigger BISales
no cascade before insert on sales
referencing new as N
for each row
begin atomic
    set (N.tickets_sold,N.desk,N.ts)=(
        select
            tickets_lock,
            desk,
            current timestamp
        from
            locks
        where
            locks.route_num=N.route_num
            and locks.departure_dt=N.departure_dt
                and locks.desk=N.desk
        );
end
@
commit@

----------------------------------------------------------
-- После того как все продано увеличиваем кол-во проданных
-- билетов в расписании и снимаем блокировку с билетов
----------------------------------------------------------
create trigger AISales
after insert on sales
referencing new as N
for each row
begin atomic
    update routes
        set tickets_sold=tickets_sold+N.tickets_sold
            where routes.route_num=N.route_num
                    and routes.departure_dt=N.departure_dt;
    delete from locks
        where locks.desk=N.desk;
end
@
commit@
...
Рейтинг: 0 / 0
Задача для версионника
    #32826816
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
причем работа проходит в режиме Uncommited Read (грязное чтение)
...
Рейтинг: 0 / 0
Задача для версионника
    #32826826
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman Можно поработать на складе. Предположим у нас есть 100 ящиков какого-то товара. И в разных филиалах его продают. сначала - оформление документов (выписка фсяких накладных и пр...). И чтоб пока документы оформляются - наши ящики не ушли кому-нить другому. Все - одной транзакцией.
В общем - условия - те же...

Бред. При чем здесь транзакции? Не видел ни одного заказчика, который описывая
требования к системе упомянул бы условие "Все - одной транзакцией".

А вот условие "что бы ящики не ушли" решается элементарно при правильном
проектировании. Например введением понятия "резервирование", которое
может происходить еще до выписки документов.

--
http://talk.ru/forum/talk.ru.accounting.development
...
Рейтинг: 0 / 0
Задача для версионника
    #32826836
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
системы всякие бывают...)) требования разные... но подходы к решению проблем могут быть одними и теми же...
...
Рейтинг: 0 / 0
Задача для версионника
    #32826841
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты зря не привел скрипт создания инстанса с включением в пост всех скриптов Оракла. Было бы нагляднее.

Ответь мне на вопрос - а где учет мест? Ведь тому мужику, что насилует кассиршу, надо плацкартные НЕБОКОВЫЕ. А если их назавтра нет, то он поедет послезавтра.

причем работа проходит в режиме Uncommited Read (грязное чтение)
Ты мне просто скажи - на каком вокзале это работает? В каком городе? А то вдруг я туда поеду. Предупрежден - уже вооружен.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826850
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы еще про бронирование забыли. Это когда деньги еще не уплачены, а билеты уже формально проданы (то есть их нет в наличии в кассе).

Значит ли это с точки зрения автора топика, что транзакция закончится только когда человек придёт и выкупит билеты реально.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826916
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanсистемы всякие бывают...)) требования разные... но подходы к решению проблем могут быть одними и теми же...
Странная задача на самом деле.
В начале вы намекаете что сущьность места не нужна (едем в электричке?) достаточно кол-ва свободных мест в поезде, а потом очень долго забиваете паспортные данные (куда?).
Т.е. система учитывает сколько свободных мест и какие паспорта едут в этом поезде?
...
Рейтинг: 0 / 0
Задача для версионника
    #32826944
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
))) Ну уж нет, раздувать простой пример до решения для МПС я не намерен...))
так что решение с плацкартом и СВ с девушкой для Сереги - предоставим кому-нить другому.
Ладно, более подробно, как это все работает:
1) К 1 окошку подходит гражданин и заказывает 600 билетов
set isolation ur
insert into locks values ('C100','31.12.2004',600,1)
DB20000I Команда SQL выполнена успешно.

гражданин сует кучу паспортов, бабки и ждет когда его оформят по полной программе.
2) Ко 2 окошку подходит другой гражданин и пытается заказать 500 билетов:
set isolation ur
insert into locks values ('C100','31.12.2004',600,2)
SQL0438N Программа генерирует ошибку с текстом диагностики: "Too many
tickets". SQLSTATE=75001

Срабатывает триггер BILocks, мэн получает отлуп по полной программе и уходит, а к окошку подходит следующий
и заказывает 4 билета
insert into locks values ('C100','31.12.2004',4,2)
DB20000I Команда SQL выполнена успешно.

--от автора:
Код: plaintext
1.
2.
3.
4.
5.
6.
db2 => select * from locks
ROUTE_NUM DEPARTURE_DT TICKETS_LOCK DESK
--------- ------------ ------------ -----------
C100       31 . 12 . 2004              600             1 
C100       31 . 12 . 2004                4             2 
   2  записей выбрано.

3) во втором окошке все напечатали, бабки приняли и делается:

insert into sales (route_num,departure_dt,desk) values ('C100','31.12.2004',2)
commit

срабатывает триггер BISales, чтобы продать именно столько билетов сколько было заблокировано и срабатывает триггер AISales, который обновляет кол-во проданных билетов в routes. Тут же делается commit, поэтому таблица routes не блокируется надолго. А блокировки в таблице locks от 2 окошка на 4 билета снимается.
--от автора

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
db2 => select * from locks

ROUTE_NUM DEPARTURE_DT TICKETS_LOCK DESK
--------- ------------ ------------ -----------
C100       31 . 12 . 2004              600             1 

   1  записей выбрано.

db2 => select * from sales

ROUTE_NUM DEPARTURE_DT TICKETS_SOLD DESK        TS
--------- ------------ ------------ ----------- --------------------------
C100       31 . 12 . 2004                4             2   2004 - 12 - 14 - 15 . 21 . 26 . 515000 

   1  записей выбрано.

db2 => select * from routes

ROUTE_NUM DEPARTURE_DT TICKETS_CNT TICKETS_SOLD
--------- ------------ ----------- ------------
C100       25 . 12 . 2004            1000              0 
C100       26 . 12 . 2004            1000              0 
C100       27 . 12 . 2004            1000              0 
C100       28 . 12 . 2004            1000              0 
C100       29 . 12 . 2004            1000              0 
C100       30 . 12 . 2004            1000              0 
C100       31 . 12 . 2004            1000              4 

   7  записей выбрано.

а в это время в 1 окошке все еще незаконченная транзакция по продаже 600 билетов все еще висит, нужное кол-во билетов блокировано... а тем временем 2 окошко может обслуживать следующего потенциального пассажира.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826948
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
теперь можете критиковать....
...
Рейтинг: 0 / 0
Задача для версионника
    #32826987
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman))) Ну уж нет, раздувать простой пример до решения для МПС я не намерен...))
Так ты для детской пластмассовой ЖД что ли? Тогда пойдет.

gardenmanтак что решение с плацкартом и СВ с девушкой для Сереги - предоставим кому-нить другому.
Вот так всегда.

gardenman1) К 1 окошку подходит гражданин и заказывает 600 билетов
set isolation ur
insert into locks values ('C100','31.12.2004',600,1)
DB20000I Команда SQL выполнена успешно.

гражданин сует кучу паспортов, бабки и ждет когда его оформят по полной программе.
После ввода 599 паспортов система вешается и "спасает" ситуацию только комбинация из трех пальцев. В системе благополучно залочено 600 мест.
...
Рейтинг: 0 / 0
Задача для версионника
    #32826993
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
увы... транзакция благополучно откатится.
...
Рейтинг: 0 / 0
Задача для версионника
    #32827004
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поддерживаю Серегу :)

И еще:
автора в это время в 1 окошке все еще незаконченная транзакция по продаже 600 билетов все еще висит, нужное кол-во билетов блокировано...
Объясните, зачем вам тут транзакция??? Общая, одна на все 600 билетов, зачем? Вы что, по-человечески, без транзакции, не можете спокойно зарезервировать 600 билетов для пластмассовой ЖД и потом оформлять их хоть три дня подряд?

И еще
автор-- Продаем именно столько билетов, сколько заблокировали
Так вы еще их скопом продаете? Не по одному? А зачем такой гимор? А если придется сделать комбинацию из трех пальцев - ту, что постом выше - то и информация всех 599 паспортов улетит в ж.. это, в трубу?

Круто!

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32827014
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну я надеюсь, судя по всему, что Экспресс-2 (и 3) не по такой схеме делали, иначе бы вокзал дневное количество билетов месяц продавал бы

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32827618
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Опять никто никого не понял... Или я никого не понял, но сделал следующие выводы:
1) Разделить понятия транзакций с СУБД и транзакций с кассиршой
2) Таблица с блокировками - кривая система резервирования

Блокировки допустимы только во время проведения операций с базой. Взятие денег, ввод данных - не операция с базой, а операция с клиентом.
Блокировки нужны более высшего уровня.
Операция резервирования и операция реализации лежат в одной таблице, которая привязана к таблице с рейсами. Их различие ведется по статусу. На кол-во свободных мест стоит ограничение >0. Если кто-то захочит вставить лишнее - не выйдет. Сначала добавляем икс билетов в расход со статусом зарезервировано, триггером снимаем этот икс с таблицы со свободными местами. Затем кассир вбивает свою муть получает деньги и переводит статус в продано. Если при срабатывании триггера срабатывает ограничение, то кассир обламается с резервированием - и вбивать ничего не придется. Если клиентский комп отвалился, то тетка решает, вешать ли ей табличку "технический перерыв", то ли ждать разрешения проблемы связи. При возобновлении связи в первом случае она удаляет резерв, во втором доводит дело до конца.
Если необходим учет разновидности мест(товарной сущности), то это надо соответственно отразить в предложенном варианте.
Почему все бьются над одной и той же проблемой, и все время призывают в помощь уровни изоляции???!! И лень поискать на форуме. Здесь уже обсуждался похожий пример, только там был склад и выписывание товара, что по сути одно и тоже. Ссылку не дам, лень искать. Думайте, господа, над сущностью телодвижений "клиентов" и их взаимосвязью.
...
Рейтинг: 0 / 0
Задача для версионника
    #32828073
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 iLLer
Правильно все понял - мы о том же и говорим с Серегой.


-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32828075
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Усиленное решение".
Я так понимаю единственная проблема была в триггере BILocks, дескать он может сработает не совсем так как нужно в конкурентной среде. Т.е. Я и Ёжик намекал на то, что всеже могут быть проданы лишние билеты (особенно если убрать CHECK CONSTRAINT AtCnt на таблице ROUTES).
Конечно же я осознаю, что то, что сейчас здесь будет нарисовано не будет работать ни на одной из известных мне баз кроме DB2.
Напишем хранимую процедуру на С++ в которой создадим именнованный мьютекс. Таким образом получится что инсертить в таблицу LOCKS (вместе со срабатыванием соответствующего триггера BILocks) в один момент времени может только один клиент.

Makefile
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
DBNAME=test
DBUSER=db2admin
DBPASSWORD=ibmdb2

TARGET=reserve.dll
DEF=reserve.def
LIBS=db2api.lib

CPPOBJS=reserve.obj
CFLAGS= -Z7 -O2 -G5 -c -W2 -D_X86_= 1  -DWIN32 -GR -GX
LINKFLAGS= /DEBUG /DLL

.SUFFIXES:
.SUFFIXES: .obj .sqx .cpp

.cpp.obj:
	cl $(CFLAGS) $*.cpp

.sqx.obj:
	echo CONNECT TO $(DBNAME) USER $(DBUSER) USING '$(DBPASSWORD)' > $*.db2
	echo PREP $*.sqx BINDFILE >> $*.db2
	echo BIND $*.bnd >> $*.db2
    @if exist $*.log del $*.log
    d:\sqllib\bin\db2clpex db2 -z $*.log -vf $*.db2
    type $*.log
	cl $(CFLAGS) $*.cxx

$(TARGET): $(CPPOBJS) Makefile $(DEF)
	link $(LINKFLAGS) -out:$(TARGET) $(SQXOBJS) $(CPPOBJS) $(LIBS) -def:$(DEF)
    copy $(TARGET) d:\sqllib\function

reserve.def
Код: plaintext
1.
2.
LIBRARY reserve
EXPORTS reserve

reserve.sqx
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <sqlenv.h>
#include <sqludf.h>

#define CREATE_MUTEX  1 
#define RELEASE_MUTEX  0 

SQL_API_RC SQL_API_FN reserve (
	char *pRoute_Num,
    char *pDeparture_Dt,
    sqlint32 *pTickets_Lock,
    sqlint32 *pDesk
)
{
	struct sqlca sqlca;
    EXEC SQL BEGIN DECLARE SECTION;
		char (*pRN)[ 5 + 1 ]  = (char(*)[ 5 + 1 ])pRoute_Num;
	    char (*pDT)[ 10 + 1 ] = (char(*)[ 10 + 1 ])pDeparture_Dt;
    	sqlint32& pTL     = *pTickets_Lock;
        sqlint32& pD      = *pDesk;
    EXEC SQL END DECLARE SECTION;

	HANDLE h=CreateMutex(NULL,FALSE,"Locker");
    if (h==NULL) {
    	strcpy(sqlca.sqlstate,"75001");
        return  0 ;
    }
    DWORD rc=WaitForSingleObject(h,INFINITE);
   	switch(rc) {
    case WAIT_OBJECT_0:
    	break;
    case WAIT_FAILED:
    case WAIT_ABANDONED:
    case WAIT_TIMEOUT:
	default:
   		CloseHandle(h);
    	strcpy(sqlca.sqlstate,"75002");
        return  0 ;
    }

    EXEC SQL INSERT INTO LOCKS
    	(ROUTE_NUM,DEPARTURE_DT,TICKETS_LOCK,DESK)
        VALUES (:pRN,:pDT,:pTL,:pD) WITH UR;

    ReleaseMutex(h);
   	CloseHandle(h);

	if (SQLCODE) {
    	pTL=- 1 ;
    }
	return  0 ;
}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
connect reset@
connect to test@

drop procedure reserve(char( 5 ),date,integer,integer)@


create procedure reserve(
	in Route char( 5 ),
    in Departure date,
    inout TicketsCnt integer,
    in Desk integer
)
modifies sql data
not deterministic
language c
external name 'reserve!reserve'
fenced threadsafe
no external action
parameter style db2sql
@

----------------------------------------------------
-- небольшое тестирование производительности
----------------------------------------------------
create procedure testrs(inout start timestamp,inout stop timestamp) 
language sql
begin
	declare desk integer default  1000 ;
    declare cnt integer default  1 ;
    set start=current timestamp;
    while desk> 0  do
    	call reserve('C100',cast('25.12.2004' as date),cnt,desk);
        set desk=desk- 1 ;
    end while;
    set stop=current timestamp;
end
@

quit@

=================================================
-- Результаты выполнения
=================================================

db2 => call testrs(NULL,NULL)

  Value of output parameters
  --------------------------
  Parameter Name  : START
  Parameter Value :  2004 - 12 - 15 - 02 . 27 . 00 . 937003 

  Parameter Name  : STOP
  Parameter Value :  2004 - 12 - 15 - 02 . 27 . 03 . 531000 

  Return Status =  0 

db2 => select count(*) from locks

 1 
-----------
        1000 

   1  record(s) selected.

db2 => rollback
DB20000I  The SQL command completed successfully.
db2 => select count(*) from locks

 1 
-----------
           0 

   1  record(s) selected.

db2 =>



-------------------------------------------------
-- блокируем 200 билетов в 1 окошке
-------------------------------------------------
db2 => set isolation ur
DB20000I  The SQL command completed successfully.
db2 => call reserve('C100','26.12.2004', 200 , 1 )

  Value of output parameters
  --------------------------
  Parameter Name  : TICKETSCNT
  Parameter Value :  200 

  Return Status =  0 

db2 =>


--------------------------------------------------------------
-- пытаемся блокировать 991 билет во 2 окошке - не получается
-- т.к. 991+200 > 1000
--------------------------------------------------------------
db2 => call reserve('C100','26.12.2004', 991 , 2 )

  Value of output parameters
  --------------------------
  Parameter Name  : TICKETSCNT
  Parameter Value : - 1 

  Return Status =  0 


---------------------------------------
-- десять билетов блокируется запросто
---------------------------------------
db2 => call reserve('C100','26.12.2004', 10 , 2 )

  Value of output parameters
  --------------------------
  Parameter Name  : TICKETSCNT
  Parameter Value :  10 

  Return Status =  0 

db2 =>

таким образом чтобы заблокировать соответствующие билеты с 1000 станций
(начать соответствующие транзакции, каждая из которых может кончится когда угодно, не мешая другим и при этом всё будет согласовано и ни каких лишних билетов на машине с Celeron 1300 в качестве сервера уйдет примерно 4 секунды.
...
Рейтинг: 0 / 0
Задача для версионника
    #32828129
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я уже начинаю думать, что мы со слепым тут разговариваем - не видит человек ничьих постов, кроме своих, ну хоть ты тресни.
Доктор....... Доооооктооооорррррр......................рррррр.....рррр..... :)

авторНапишем хранимую процедуру на С++ в которой создадим именнованный мьютекс. Таким образом получится что инсертить в таблицу LOCKS (вместе со срабатыванием соответствующего триггера BILocks) в один момент времени может только один клиент.
Инсертить всегда в один момент времени может только один клиент, особенно если он использует транзакцию.

gardenman начать соответствующие транзакции , каждая из которых может кончится когда угодно, не мешая другим и при этом всё будет согласовано и ни каких лишних билетов на машине с Celeron 1300 в качестве сервера уйдет примерно 4 секунды
Может вы все же объясните, что вы понимаете под транзакциями в данном контексте???

=============
Сам с собой человек разговаривает - круто, да? А зачем на форус обратился? Чтобы его гениальный алгоритм все увидели? Дык увидели, и даже прокомментировали.... Что же еще?
-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32828492
Фотография Я и ёжик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman"Усиленное решение".
Вообще существует ещё много интересных и не менее полезных занятий в этом мире, например изобретение вечного двигателя.


gardenman
Я так понимаю единственная проблема была в триггере BILocks,

Не единственная, а первая попавшаяся на глаза . В Вашу синхронизацию как минимум надо включить оба ваши триггера на sales и и все возможные операции на routes, только тогда можно будет ожидать корректных результатов. Т.е. по сути Вы ВСЕ операции с базой данных над таблицами locks,sales, routes выстраиваете в очередь, т.е сериализуете ( как вам и говорил vc123) только не на уровне БД а на уровне OS, искусственно выделив из сериализации часть транзакции по вводу данных паспортов. Не проще ли выделить этот ввод в отдельную транзакцию и не мучиться изобретением велосипедов?

tygra Я уже начинаю думать, что мы со слепым тут разговариваем - не видит человек ничьих постов, кроме своих, ну хоть ты тресни.
Он же сказал уже: "Смысл того, что здесь написано совсем другой. И я имел в виду совсем не то, о чем ты подумал. Я хочу сказать что существует класс задач, для которых Оракл не катит." Его не интересует как "правильно и эффективно" решить реальную задачу, он хочет показать, что в такой кривой постановке её можно решить только на блокировочнике с грязным чтением.
...
Рейтинг: 0 / 0
Задача для версионника
    #32829376
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В упор не вижу причин для:
1) Невозможности реализации на Oracle или любой другой SQL-СУБД. И даже не столько невозможности, сколько не профильности. Если у Вас будет один сервак и тыща касс, то многие СУБД могут загнуться.
2) Необходимости применения уровней изоляции (не блокировок, так как это понятие растяжимое). Необходимо разделить понятия транзакционности. То ли для Вас транзакция - это факт изменения данных в БД, то ли факт оформления покупки. И совершенно не обязательно одно натягивать на другое.
3) Необходимости применения синхронизации работы клиента (А какого черта Вы тогда вообще в СУБД лезете, еще чуть-чуть подправить, организовать хранилище данных в файле, и будет совсем автономная система, а вернее СУБД). СУБД для того и нужна, чтоб организовать надежный доступ многих страждующих к одним данным и она берет на себя задачу сериализации транзакций.
Пора призывать модераторов закрывать эту тему. Ибо начальный вопрос потерян и не уместен в данном контексте.
...
Рейтинг: 0 / 0
Задача для версионника
    #32829871
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Его не интересует как "правильно и эффективно" решить реальную задачу, он хочет показать, что в такой кривой постановке её можно решить только на блокировочнике с грязным чтением.

1) Хотел бы увидеть почему моё решение неправильное. Пожалуйста - аргументы. Хотите сказать что оно не работает? Привидите такую последовательность действий над системой, когда результат будет не таким, каким я его ожидаю.
2) Почему моё решение неэффективное? У вас есть более эффективное? требующее меньшего I/O, меньших затрат на програмимирование, увеличивающее параллелизм?

>Пора призывать модераторов закрывать эту тему
У нас появился цензор? Меня записали в еретики? Сожжете на костре?

3) У каждой задачи существует множество решений, также, как существует множество людей. И увы, не нам решать имеют ли они право на существование.

Теперь еще раз медленне и подробнее.
Два пользователя хотят изменить в записи поле с остатком.
пользователь А делает select for update nowait - блокирует запись.
Пользователь Б также делает select for update nowait - и получает отлуп. Если он сделает просто select for update - то подвиснет до тех пор, пока А не сделает commit.
Таким образом они редактируют запись по очереди . И от этого конечно не избавиться ни в одной системе. Но в отличие от версионника, блокировочник может построить очередь из таких незавершенных запросов (транзакций) и, спрогнозировав сколько билетов осталось в кассе ( несмотря на то, что еще не все транзакции закоммичены ) сказать - можете не занимать очередь, вам все равно не хватит. Но если хотите испытать судьбу - подождите. Может вам и достанется.

Или, например в другом случае, не просто дать отлуп на select for update nowait, а сказать - знаете, а эту запись редактирует сейчас Вася Пупкин, который сидит этажом выше, и хочет списать со счета 50 баксов, на счете останется еще 100 баксов. И, если вы хотите снять в пределах этих ста баксов - то пожалуйста - путь свободен. Если больше - то извините...((

За сим прощаюсь с вами. Всем удачи.
...
Рейтинг: 0 / 0
Задача для версионника
    #32829976
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 gardenman
ИМХО. Все твои ухищрения основаны на желании открыть транзакцию при обращении пасажира и закрыть ее после ввода 600 документов. Я тебе в самом начале описал как можно сделать в системах с высокой конкуренцией за данные. Просто для этого надо продумывать соответствующую структуру данных. Извращаться на хреновой (гипотетически упрощенной и отвлеченной от конкретной задачи) структуре с уровнями изоляции конечно можно, но непродуктивно. Опять же повторюсь - ИМХО .
...
Рейтинг: 0 / 0
Задача для версионника
    #32830119
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to gardenman:
1) Никто не говорит, что Ваше решение неправильное. Вообще в жизни нет такого понятия, как правильно.
2) На счет меньших затрат на программирование - это точно. В Вашем варианте Вы делаете работу (по программированию), которую должна выполнять СУБД.
3) Я не цензор, это мое мнение
4) Все имеют прваво на существование
5) Также медленно: к чему вообще селект? В том смысле зачем Вам селект в одной транзакции с апдейтом?
Первая транзакция: селект состояния по билетам, далее по желанию вывод на экран, сохранение в файл, распечатка, отсылка и т.д.
Вторая: клиент посылает апдейт на изменение значения доступного кол-ва либо добавляет в систему документ о проведении операции резервирования, которая влечет изменения статусов доступности. В зависимости от реализации.
Если вторая транзакция вернулась с ошибкой, то все ясно, мест нет. И можно сразу смело посылать покупателя, т.к. мест нет. Если места есть, то вбиваются детали и переводится состояние из "резерв" в "продан".
Поднимитесь вверх и медленно прочтите мое предложение о реализации системы резервирования. Я уже это писал. И не только я. А с прогнозированием это Вы загнули.
...
Рейтинг: 0 / 0
Задача для версионника
    #32830471
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да не слышит человек ни одного другого, отличного от его самого, мнения и решения. Придумал кошмар ночной и радуется до смерти. До смерти - это потому, что помрут все с такой реализацией.

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

Ээээхххххххх

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32833384
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошие вы все ребята, душевные....
Я сначала было подумал не отвечать... но блин вчера было так скучно и тоскливо в форуме... А вообще чем попусту сотрясать воздух (а ля тигра) я предпочитаю сначала подумать, а потом дать аргументированный ответ.

Для начала несколько ситуаций:
1) Студент вытаскивает на экзамене говорит препаду: 13 билет, но отвечать я буду на 1 билет, потому, что я только его выучил
2) Заказчик приходит к подрядчику и говорит: вот нужно написать такую-то систему, можете ее реализовать на Оракле. Подрядчик - конечно можем...так что тут у Вас? а.. отлично, мы беремся, вот только реализация будет на MSSQL и вот это и это вы как-нить сами...
3) Если кто-то расписался в своем бессилии доказать теорему Ферма, то не проще было бы поменять вообще эту теорему, так сказать изменить условия задачи?

Ситуация из жизни, с которой я сталкиваюсь ежедневно на работе: представляете (сразу говорю, автор не я!!!!) у нас параметры в ХП передаются через запись в постоянной таблице!!!
А что это значит? То, что если человеку взбредёт в голову войти под своим своим логином с двух компов, то получится конфликт параметров!

Рассмотрим подробнее ситуацию с резервированием. Сия ситуация означает, что транзакций в системе будет несколько. Одна с резервированием, другая - собственно с продажей. Следовательно записи на резервирование нужно как-то идентифицировать. Варианты: по имени пользователя, по номеру сессии, по коду терминала.
1)По имени пользователя: если это так, то с двух терминалов под одним и тем же именем не зайти - конфликт параметров ХП (смотрите ситуацию, описанную абзацем)
2)По номеру сессии: в случае глюка/отсоединения терминала мы теряем номер сессии, придется каким-то образом оперативно чистить зарезервированные билеты.(у Оракла ведь есть триггер на закрытие соединения? в любом случае у MS такого точно нет). А как тогда быть с внесенными вами данными по 599 паспортам? *я читаю внимательно все что вы пишете, и ищу контраргументы*.
3)По коду терминала: та же самая ситуация что и по номеру сессии.

Знаете, ну как-то влом писать сборщик мусора, который в тоже время должен отрабатывать достаточно оперативно. Намного более дешевое (с точки зрения I/O) и простое решение - просто откатить транзакцию.

Вы думаете задача представленная здесь - единственная в своем варианте?

Есть еще одна задачка над которой все думают и все решают по-совему. Нужно зачислить на счета зарплату 100000 человек. Предположим в компе уже имеется этот список в какой-то таблице. Хотите пообсуждать как будет выглядеть такое решение? С учетом, что в системе работает сразу несколько сотен юзеров? Как сделать так, чтобы все отработало в приемлемые сроки с минимумом накладных расходов? Или, например, как сделать так чтобы эта операция была распараллелена между несколькими процессами и количество конфликтов было бы минимальным?

Ситуация из жизни (у меня на работе, делал не я ). Идет прием бланков строгой отчетности (БСО). Имеется документ на 20000 бланков. У каждого бланка свой индивидуальный номер. Бланки должны быть приняты одновременно (документ-то один! сервер Sybase ASE). Рузультат: После небольшого скандала документ решили разбить на 4 по 5000. Понятное дело - просто криво спроектированна реализация. А как бы вы решали эту задачу?
...
Рейтинг: 0 / 0
Задача для версионника
    #32833392
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задачка специально для tygra, как для любителя MSSQL:
Предположим, у нас имеется некий набор договоров. Над определенной группой договоров мы должны провести некую группу однотипных операций, например - банальное расторжение. Задача - Оператор в гриде на своем рабочем месте помечает эти договора (например заносит их id во временную таблицу) а затем передает этот список в ХП, которая все их закрывает. Затем дополняет список этих договоров еще некоторым количеством договоров (отбирая их по какому-нибудь критерию), а затем - передает их другой ХП, которая их переоформляет на новых условиях. Затем чистит пометки и повторяет операцию снова. Как это будет выглядеть на MSSQL? Понятное дело что временная таблица должна быть создана не в какой либо ХП, а самим приложением. И это должна быть не таблица с ##, потому как в этом случае она будет доступна всем сесииям. А тепрь еще наложим условие, что приложение у нас написано,исходников нет, и код мы можем только на сервере.
...
Рейтинг: 0 / 0
Задача для версионника
    #32833550
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
авторНо в отличие от версионника, блокировочник может построить очередь из таких незавершенных запросов (транзакций) и, спрогнозировав сколько билетов осталось в кассе (несмотря на то, что еще не все транзакции закоммичены) сказать - можете не занимать очередь, вам все равно не хватит.

^^^
это как :) что-же есть такое в блокировочнике чего не может select for update и оракловые пользовательские блокировки ? похоже я что-то грандиозное пропустил :)

к стате а db2/mssql могут указывать сколько ждать на запросе, у оралового можно указать в секундах сколько ждать типа select ... for update wait 30 (точно синтаксис не помню) ?

ЗЫ. МПС работает на SAP + oracle и как-то умудряется зарплату расчитать :)
http://ru.sun.com/win/sales/transport/mps.html
...
Рейтинг: 0 / 0
Задача для версионника
    #32833557
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бред.
Хоть задачка и не для меня, скажу, что она из разряда:
"Хачу, пнимаешь, на Луну, только чтоб на Жигулях, бензин был в качестве топлива, и без водителя". Такого не бывает. Либо на Жигулях, либо без водителя, либо на бензине, но не одновременно, всему есть предел.
А то, что параметры в процедуру передаются через таблицу - это вообще отдельный разговор, который не связан с блокировками и транзакциями. И тем более с тем, как сохранять целостность в системе. Если Вы не можете решить одну проблему нормальным путем, не создавая себе при этом других, то это не значит, что нет таких решений, при которых не возникает других проблем.

А про ситуацию с резервированием могу добавить:
Если возникает необходимость сделать монопольный доступ к зарезервированым местам, то это необходимо сделать ("Хочешь быть счастливым - будь им"(с) Козьма Прутков). Только он организован не на системе блокировок в СУБД, а на более высоком уровне. Т.е. запись о резервировании принадлежит пользователю (сессии - не очень хорошо). Отвалился - никто твой резерв не возьмет. Включился - будь добр определи судьбу твоих резервов, либо сними (если клиент свалил), либо утверди (если клиент дождался), и только потом продолжай работу в штатном режиме.
...
Рейтинг: 0 / 0
Задача для версионника
    #32834112
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanСитуация из жизни, с которой я сталкиваюсь ежедневно на работе: представляете (сразу говорю, автор не я!!!!) у нас параметры в ХП передаются через запись в постоянной таблице!!!

gardenmanСитуация из жизни (у меня на работе, делал не я ).

Не хочу никого обидеть, но бывает ситуация, когда делал ты? Почитаешь тебя - вообще ничего сделать нельзя ни на чем. Чем тогда люди занимаются?

Если у тебя возникает множество вопросов, то лучше спрашивать их отдельными топиками. И не объявлять заранее, что у тебя уже есть самое правильное решение.
...
Рейтинг: 0 / 0
Задача для версионника
    #32834559
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я даже и не знаю теперь, отвечать или нет?

Оказалось, что я (да и все) тут продвигают MS SQL - хотя даже уже кричали, что в самомо начале топика предложено универсальное решение для любой БД, причем единственно правильное.

авторРассмотрим подробнее ситуацию с резервированием. Сия ситуация означает, что транзакций в системе будет несколько. Одна с резервированием, другая - собственно с продажей.
Точно. Только они короткие очень - 1. зарезервировать билеты 2. сделать продажу. Все, никаких ваших висячих транзакций.
автор Следовательно записи на резервирование нужно как-то идентифицировать. Варианты: по имени пользователя, по номеру сессии, по коду терминала.
Да как хотите - все зависит от того, как будут работать с системой
автор1)По имени пользователя: если это так, то с двух терминалов под одним и тем же именем не зайти - конфликт параметров ХП (смотрите ситуацию, описанную абзацем)
См. Предыдущий комментарий. Если входить можно только с одного места - то можно и так.
автор2)По номеру сессии: в случае глюка/отсоединения терминала мы теряем номер сессии, придется каким-то образом оперативно чистить зарезервированные билеты.(у Оракла ведь есть триггер на закрытие соединения? в любом случае у MS такого точно нет).
Несколько раз приводился готовый код для таких вещей.
авторА как тогда быть с внесенными вами данными по 599 паспортам?
Это как быть с внесенными вами 599 паспортами - у меня то нет одной большой открытой транзакции, я все эти 599 билетов с паспортами внес и продал . А вы все это потеряли
автор*я читаю внимательно все что вы пишете, и ищу контраргументы*.
Плохо ищите - совсем не то.
автор3)По коду терминала: та же самая ситуация что и по номеру сессии.
И те же самые комментарии.

авторЗнаете, ну как-то влом писать сборщик мусора, который в тоже время должен отрабатывать достаточно оперативно. Намного более дешевое (с точки зрения I/O) и простое решение - просто откатить транзакцию.
Ну раз в лом - об чем разговор. В лом и систему писать - нафиг надо? :) Вы уж тогда проще сделайте - при старте клиентского приложения открывайте одну транзакцию, здооооровенную, а при закрытии - коммит. А если вруг сбой - ну ничего, день потеряете, зато не в лом

авторЗадачка специально для tygra, как для любителя MSSQL:
Не вижу ничего такого в "задачке", что бы ее относило к MS SQL
авторПредположим, у нас имеется некий набор договоров. Над определенной группой договоров мы должны провести некую группу однотипных операций, например - банальное расторжение. Задача - Оператор в гриде на своем рабочем месте помечает эти договора (например заносит их id во временную таблицу) а затем передает этот список в ХП, которая все их закрывает. Затем дополняет список этих договоров еще некоторым количеством договоров (отбирая их по какому-нибудь критерию), а затем - передает их другой ХП, которая их переоформляет на новых условиях. Затем чистит пометки и повторяет операцию снова. Как это будет выглядеть на MSSQL? Понятное дело что временная таблица должна быть создана не в какой либо ХП, а самим приложением. И это должна быть не таблица с ##, потому как в этом случае она будет доступна всем сесииям.
Ну кто как хочет - кто через #t, кто по одному документу.
авторА тепрь еще наложим условие, что приложение у нас написано,исходников нет, и код мы можем только на сервере.
Так вы определитесь - или задачку решать или менять ничего нельзя. Или по-русски объясните, что значит и код мы можем только на сервере ?

А кстати, что вас так смутило в этой так сказать "задачке"? Не смогли решить для MS SQL?

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

У вас есть какие-то проблемы? С Ораклом? С MS SQL? Так вы скажите прямо - расскажем, чего знаем. Чего странными "задачками" прикрываться?

ЗЫ Ничего не понимаю................

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32875106
_Wolf_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
gardenmanимеется запись
insert into routes
(route_num,departure_dt,tickets_cnt,tickets_sold)
values ('C100','31.12.2004',1000,950)


видно, что было 1000 билетов, 950 из которых - продано.=> осталось 50 билетов.
Иммется два окошка. К первому подходит гражданин, и пытается 2 купить билета.
Кассарша начинает транзакцию, говорит:
select ... for update. Запись - блокирована.
К другому окошку подходит другой мэн...и просит 2 билета на тот же рейс.
Ну и другая кассирша тоже делает select ... for update на ту же запись...
ну и как им быть? Ждать пока кассирша в первом окошке не расчитается с клиентом и не сделает commit?

После первого селекта запись уже заблокирована, и ни в одной нормальной системе 2ая касирша не сможет обновить заблокированную запись, что не понятного?
...
Рейтинг: 0 / 0
Задача для версионника
    #32875569
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman
Задача:
1) Продажа проходит одной транзакцией
2) Продажа (транзакция) растянута во времени (до получаса)
3) продавать билеты на один и тот же рейс могут одновременно из нескольких окошек.

Ну это явно надуманная постановка задачи.
Задача - продавать билеты, а не программировать транзакции.
Представим всего один московский вокзал. 45 суток * 500 мест * 100 поездов = 2,25 млн мест, в день в среднем бронируется/продается 50000.
50000 / 24 часа работы касс / скажем, 3 минуты на операцию = 100 одновременно открытых транзакций.
А теперь - смертельный номер - умножим это на количество вокзалов (или станций РЖД?! я туплю). Капец.
Что-то слабо верится что какое-либо железо способно с этим справиться. Транзакции надо открывать на момент записи, только чтобы обеспечить отсутствие двойной продажи (ну и двойного резервирования тоже).

ЗЫ. Я не продаю железнодорожные билеты. Я так, прикалываюсь. 3 минуты - из практики стояния в очереди за билетами.
...
Рейтинг: 0 / 0
Задача для версионника
    #32875582
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Транзакции нужно открывать тогда, когда нужно и держать столько, сколько нужно по требованиям бизнеслогики. (С) Том Кайт (правда немного не точно, т.к. нет под руками первоисточника)
...
Рейтинг: 0 / 0
Задача для версионника
    #32875853
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый Садовник,
Извините за нескромный вопрос, Вы где работаете - или хотя бы кем? Оч. похоже, что основное Ваше занятие - разведение кактусов, а с SQL Вы решили поразмяться, шоб мозги на затухли. Достойное решение!

Я извиняюсь за сей _грубый_ (не спорю) вопрос, точнее комментарий, так как он ответа не предпологает. Причина тому такова, что в 99% случаев либо нам деньгу плотять, за то что мы рожаем что-то, либо мы сами деньгу получить за свой труд надеемси. Ну 1% - так хобби, развлекалочка. Вот сей _проект_ развлекалочка и есть. Рожать надоть _работающие_ программы (плохо ли, хорошо ли - вопрос другой, хотя лучше, шоб хорошо...) _Неработающие рожать не надо, какие бы они красивые не были...

Лирическое отступление
Самая безошибочная программа - это та, что выдает "Hello, World". Она же и самая бестолковая, никому не нужна...
...
Рейтинг: 0 / 0
Задача для версионника
    #32876265
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanТранзакции нужно открывать тогда, когда нужно и держать столько, сколько нужно по требованиям бизнеслогики. (С) Том Кайт (правда немного не точно, т.к. нет под руками первоисточника)
Хорошо бы привести критерии оптимальности решения, которыми автор процитированного руководствовался. Каюсь, не читал.

Я соглашусь что Ваши идеи полностью соответствуют описанию бизнес-логики, приводимой Вами в описании "задания".

Другое дело, что я пытаюсь довести до Вашего сведения, что imho описанная логика порочна и попросту неработоспособна в реальных условиях эксплуатации системы.
...
Рейтинг: 0 / 0
Задача для версионника
    #32876726
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А ему пофиг, что его решение неработоспособно. Потому-что это его решение. А если какие-то ослы будут тут советовать, да еще пальцами тыкать - дык что на них отвлекаться, у гениев на это нет времени :(=)

ЗЫ Если он все так пишет, то непозавидуешь заказчикам.

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32881012
Фотография hell
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В результате таких пейсателей я неделю назад попал в презабавнейшую ситуацию, начали мне оформлять билет, когда закончили - сказало что мест уже нет(

А по топику - в Oracle было предложено 2(два) работающих варианта

"The CBO without stats is like a morning without coffee." T.Kyte
...
Рейтинг: 0 / 0
Задача для версионника
    #32881019
Фотография hell
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanДорогой Tygra! Смысл того, что здесь написано совсем другой. И я имел в виду совсем не то, о чем ты подумал. Я хочу сказать что существует класс задач, для которых Оракл не катит .
Вот как ты думаешь, почему кластерные реализации от Оракла и от IBM такие разные? Ведь совсем не потому, что Оракл круче и совсем не потому, что IBM не могут как Оракл. А потому, что в силу своих архитектурных особенностей JОракл по-другому просто не может )


Несомненно, детей рожать оракл не катит.

ЗЫ: катится всё, но с разной скоростью
...
Рейтинг: 0 / 0
Задача для версионника
    #32881732
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дорогой Hell, в моём случае такой вариант невозможен... Ты всегда у меня будешь с билетамами по самым льготным ценам и на самые разные направления...)
...
Рейтинг: 0 / 0
Задача для версионника
    #32882050
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
2gardenman

а что за кластерная технология есть у db2 ? чем эта "технология" принципиально отличается от dblink в оракле ?
...
Рейтинг: 0 / 0
Задача для версионника
    #32882076
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про это уже много писалось в форуме с "сравнениях". Отличия принципиальные - у Оракла разделяемый диск (система хранения) у ДБ2 - просто ставится рядом еще одна машина,потом еще иеще.. и так до тысячи узлов. Короче ищите в сравнениях. Если реально нужно про кластера поспрашивать, то в форум по ДБ2. Некоторые юзают.
...
Рейтинг: 0 / 0
Задача для версионника
    #32882151
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
про различия shared nothing и ораклового shared disk архитектур я в курсе, я окуратно пытаюсь выяснить, чем оракловый dblink не аналог shared nothing "кластера" ? мне показалось вы сможете в 2х словах объяснить.
...
Рейтинг: 0 / 0
Задача для версионника
    #32882237
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Честно говоря до изучения dblink в Оракле я еще не дошел
Если проводить аналогии то, как мне кажется:
DB2 - fedefated server
Oracle - dblink
Sybase - proxy table
Все это примерно одно и то же. Только в каждой системе разные навороты и несколько разные возможности. Везде можно написать запрос который будет использовать несколько источников данных (из разных баз данных) с разной степенью тормознутости (2-х фазный коммит в случае транзакции по нескольким таблицам из нескольких баз, который делается прозрачно).
Но в случае кластера DB2 - это все одна база данных и ничего общего с двухфазными транзакциями. Это параллельная обработка одного запроса сразу несколькими компами, причем каждый работает со своей порцией данных (выделенной по хэш-функции). Т.е. это полноценное масштабирование и никакого pinging как в случае с Oracle RAC.
...
Рейтинг: 0 / 0
Задача для версионника
    #32882656
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторДорогой Hell, в моём случае такой вариант невозможен... Ты всегда у меня будешь с билетамами по самым льготным ценам и на самые разные направления...)

Возможен вариант для любого сервера.

ЗЫ А билет Hell никогда не оформит - затра..ется ждать окончания всех транзакций

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32883116
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ище одна мысль. А Вы уверенны, що у тети кассирщи Оракловый клиент будет? А я вот - нет, будет у нее ка-нить HTML форма. Тонкий клиент называется, между прочим. Послал запрос - получил новую форму. Ну и иде Ваши транзакции? CGI на сервере поднялси, в базу слазил, ответ сгенерил, усе транзакции и закрылись.
Ну пусть даже и стоит Оракловый клиент у тетки. И склольки мы бум сессию открытую держать? Никакой мощи не хватит. Хватит, конечно, я щучю. Тольки все равно это очень _не_рациональное_ решение. Я даже на уровне одного загуска CGI освобождаю сессию, если все транзакции завершились. Может, это спорно, конечно - но держать сессию пол-часа ничего не делая - чересчур.

Ездовых собак я видел, но ездовые коты - это чересчур. Трое из Простоквашино (с)
...
Рейтинг: 0 / 0
Задача для версионника
    #32883201
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Я даже на уровне одного загуска CGI освобождаю сессию, если все транзакции завершились

вот это точно не самое рациональное решение. Хотя для мелких систем с небольшой нагрузкой вполне прокатит в зависимости от длительности транзакции и количества транзакций в секунду :)) интересно было бы узнать о соотношении накладных расходов по старту сессии к собстенно работе с базой в такой системе. Вдруг окажется что половину ресурсов сервер тратит только на то, чтобы соединить/разъединить?
...
Рейтинг: 0 / 0
Задача для версионника
    #32883213
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman>Я даже на уровне одного загуска CGI освобождаю сессию, если все транзакции завершились

вот это точно не самое рациональное решение. Хотя для мелких систем с небольшой нагрузкой вполне прокатит в зависимости от длительности транзакции и количества транзакций в секунду :)) интересно было бы узнать о соотношении накладных расходов по старту сессии к собстенно работе с базой в такой системе. Вдруг окажется что половину ресурсов сервер тратит только на то, чтобы соединить/разъединить?
Много веб-серверов поставить - денег много не надо.
А если это про SQL-сервер, то тут конечно вопрос, но все же думается что не так много и стоит новый коннект по сравнению с кучей висящих транзакций.
...
Рейтинг: 0 / 0
Задача для версионника
    #32883232
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
2gardenman

у вас совсем древнии представления о веб-программировании :) даже php на mysql не открывает/закрывает конекции, а использует что-то типа пула конекций. также и cgi обычно через пул пишут.
...
Рейтинг: 0 / 0
Задача для версионника
    #32883266
drmike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yo! пишет:
> у вас совсем древнии представления о веб-программировании :) даже php на
> mysql не открывает/закрывает конекции, а использует что-то типа пула
> конекций. также и cgi обычно через пул пишут.

У уважаемого Yo! видимо представления о веб-программировании намного
более опережают сегодняшний век, так как постоянные соединения у mysql
(видимо именно это подразумевалось под умным словом "конекции")
предназначены для экономии ресурсов сервера, а никак не для удержания
текущей транзакции. А для всех cgi в рамках одной сессии держать
открытой транзакцию на весь период длительности сессии? В чем смысл?
Posted via ActualForum NNTP Server 1.1
...
Рейтинг: 0 / 0
Задача для версионника
    #32883400
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
drmike

У уважаемого Yo! видимо представления о веб-программировании намного
более опережают сегодняшний век, так как постоянные соединения у mysql
(видимо именно это подразумевалось под умным словом "конекции")
предназначены для экономии ресурсов сервера, а никак не для удержания
текущей транзакции. А для всех cgi в рамках одной сессии держать
открытой транзакцию на весь период длительности сессии? В чем смысл?
Posted via ActualForum NNTP Server 1.1

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

2. высказывание gardenman "Вдруг окажется что половину ресурсов сервер тратит только на то, чтобы соединить/разъединить " однозначно относится к конекции (connection), но никак не к транзакции.
...
Рейтинг: 0 / 0
Задача для версионника
    #32883585
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Угу, разговор пошел в новое русло, пока еще без драки (что радует). Итак, имея некий опыт веб-прграммрования эдак 5-6 лет, и при этом еще оставаясь живым, имею наглость утверждать, что
1) Накладные расходы на connection не велики, про крайне мере для Oracle и MsSQL.
2) Проблема, которую создает долго висящая transaction, дороже. Верятность схватить блокировку и все повесить дороже выйдет.

Извиняюсь за англицкие словечки - шоб понятнее было.
...
Рейтинг: 0 / 0
Задача для версионника
    #32883786
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushokНакладные расходы на connection не велики, про крайне мере для Oracle и MsSQL.Вы ошибаетесь. Можете сказать лишь следующее: "накладные расходы на connection не велики, про крайне мере для задач, с которыми я сталкивался на Oracle и MsSQL".

Наш сервер работал на оракле и постгресе. Для обоих субд использовали persistent connections (через mod_perl), так как это давало большое увеличение производительности. Недавно я писал об этом .
...
Рейтинг: 0 / 0
Задача для версионника
    #32883986
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Господа программисты, я не в коем случае не хочу утверждать что долговисящщие транзакции - это хорошо. Долго висящая транзакция у вас ассоциируется с долго висящей блокировкой (блокировка - это действительно ресурс). Но, однако, заметьте, точто я здесь предлагал - все совсем наоборот. Не ставте все с ног на голову. Несмотря на то, что, транзакция довольно продолжительная, блокировка - быстрая и безболезненная т.к. осуществляется лишь на очень короткий промежуток времени. И, честно говоря то, реализовать такое только средствами СУБД практически невозможно.
Есть такая штука как SEQUENCE, или IDENTITY. Все знают что для ускорения выдачи этих значений они как-бы генерятся предварительно. Поэтому при сбое возникает identity gap, или разрыв в sequence. А ведь можно реализовать собственную версию sequence, которая этим не страдает. Опять же, без низкоуровнего программирования тут не обойтись.
А скажите мне разве невозможно в случае зависания сессии, сначала считать ее незакомиченные данные, а затем сбросить зависшую сессию и продолжить ее работу? Возможно многое. И, как правило, такие прямолинейные действия на самом деле более работоспособны.
Часто бывает так, что программист находит какой-то инструмент, изучает его и старается приспособить ко всему. Типа - мартышка и очки. Нельзя зацикливаться. Бог любит разнообразие. Короче - смотрите чуть шире.
...
Рейтинг: 0 / 0
Задача для версионника
    #32884071
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
3 раза прочитал но чесно говоря совсем не вьехал, как транзакция в блокировочнике (db2 как я понимаю) длинная а блокировки быстрые, какие-то зависания у сессий - это сессия веб приложения имеется ввиду или сессия субд и что такое "зависание" ?
...
Рейтинг: 0 / 0
Задача для версионника
    #32884835
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я тоже первый раз прочитал - ничего не понял. Хотел второй было читать - но увидел, что Yo! и с 3-го не понял, то и я не стал читать больше. С ходу - каша какая-то, смешались в кучу люди, кони....

По коннектам: к MS SQL из asp.net можно через пул коннектов ходить, удобно однако.

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32885930
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Леха Налоговый
Я не ошибаюсь (я так думаю, вообще-то), однако, они _дейсвительно_ не велики. Хотя и зависят от многих факторов, в частности оракл и cgi на одном сервере или нет. Я таки про cgi толкую, на не про весь спектр задач, включаюших оракл. Хотя, полностью согласен, что использовнание долгоиграющей connection может увеличить производительность. Это с одной стороны, с другой увеличивается вероятность блокировки.

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

2 Садовник
Таки тоже не понятно. Кады transaction началася, она по ходу дела выставляет блокировки. И блокировки будут сняты только в момент окончания транзакции. Сделать блокировку маленькой (по времени) - значит сделать маленькой саму transaction. Или я не прав?
...
Рейтинг: 0 / 0
Задача для версионника
    #32885952
Alexey Sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПредставте себе ситуацию, когда куча пользователей одновременно что-то делают - а результаты их работы постоянно суммируются и отображаются в одном месте (строчке в таблице). Тоесть каждый пытается менять эту строчку. Все процессы выстраиваются в очередь. Минимизация времени connection в этом случае спасает - отработал, отвались

зачем "отработал, отвались" ? отработал - закоммить транзакцию и дыши спокойно. Какие в ж..у блокировки после завершения транзакции?
...
Рейтинг: 0 / 0
Задача для версионника
    #32886011
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отвались, потому что connection другим понадобиться может. Ресурс, таки. У а commit али rollback само собой разумеется, кудыж без него...
...
Рейтинг: 0 / 0
Задача для версионника
    #32886243
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
2andrushok

почитайте все таки про connection pooling, отваливается веб клиент конекция остается просто отдается следующему веб клиенту. прерывая конекцию вы ничего не выйграете, только проиграете.
...
Рейтинг: 0 / 0
Задача для версионника
    #32886281
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushok2 Садовник
Таки тоже не понятно. Кады transaction началася, она по ходу дела выставляет блокировки. И блокировки будут сняты только в момент окончания транзакции. Сделать блокировку маленькой (по времени) - значит сделать маленькой саму transaction. Или я не прав?

Абсолютно правы. А теперь с другой стороны - блокировка ставится для того, чтобы всех клиентов построить в очередь к ресурсу. Я в своем варианте слегка "расширил" возможности этого подхода позволив клиенту считывать незакомиченные, но согласованные данные построив их в очередь перед семафором. Поэтому "лишний" билетик продать невозможно. А сам ресурс (запись с количеством доступных билетов) блокируется и освобождается стандартным способом. Т.е. каждый сеанс видит количество проданных и количество "заблокированных" билетов в реальном времени.

2 Alexey Sh
andrushok - прав. запуск процесса - дорогое удовольствие. Поэтому в системах и используют сервера приложений, которые держат очередь запросов на транзакции от клиентов и пропускают эту очередь через пул соединений. Выигрыш может составить 200-300%. А может и больше.
...
Рейтинг: 0 / 0
Задача для версионника
    #32886522
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторАбсолютно правы. А теперь с другой стороны - блокировка ставится для того, чтобы всех клиентов построить в очередь к ресурсу . Я в своем варианте слегка "расширил" возможности этого подхода позволив клиенту считывать незакомиченные , но согласованные данные построив их в очередь перед семафором. Поэтому "лишний" билетик продать невозможно. А сам ресурс (запись с количеством доступных билетов) блокируется и освобождается стандартным способом. Т.е. каждый сеанс видит количество проданных и количество "заблокированных" билетов в реальном времени.
Я так и не понял, зачем вы транзакцией блокируете данные и потом из-за этого используете грязное чтение? Этого я не пойму!!!
У вас есть таблица с билетами, на которые идет оформление (если я правильно понял), зачем вам ее блокировать а потом грязно читать? Не пойму я - зачем тут блокировки на уровне транзакций? Вы что, в эту таблицу и так не можете посмотреть, чего там у вас?

И кстати, зачем выстраивать в очередь клиентов? Они сами выстроятся - когда количество менять будете в проданных и заблокированных.

Мдааааа.
Вы все-же словами - не надо скриптов - еще раз пояснили бы алгоритм.

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32886614
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
типа... последний раз попытаюсь объяснить что я имею в виду.

Оракл: Запись с количеством билетов обновлена, но коммит еще не сделан.
Никто не видит реального количества билетов. Всем доступно только предыдущее значение. Поэтому сказать точно сколько билетов еще можно продать - никто не может. (грязное чтение отсутствует как класс) Т.е. можно так выразиться (перефразировать) невозможно работать в реальном времени.
Все клиенты вынуждены вставать в очередь и ждать когда можно будет заблокировать запись и получить актуальное количество доступных билетов.

DB2: (режим - грязное чтение) видно - что запись обновлена, видно сколько в билетов на данный момент другие намериваются продать (типа зарезирвировано). Но, однако чтобы получить эти данные, и быть уверенным что пока я их читаю и резервирую некоторое количество билетов, никто их не поменял, перед считываением выставляется семафор, резервируется некоторое количество билетов (добавляется запись в таблицу Locks), затем семафор освобождается. Я начал транзакцию, но горячий ресурс с количеством свободных билетов - не заблокировал. Теперь я могу в любой момент закончить транзакцию, гарантируя что зарезервированные мной билеты имеются, и транзакция завершится удачно. (т.е. очередь к горячему ресурсу отсутствует)
...
Рейтинг: 0 / 0
Задача для версионника
    #32886623
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. я хочу сказать что при таком подходе ситуация в которую попал многоуважаемый hell (пока оформляли билет - оказалось что билетов нет(стихами заговорил))- невозможна.
...
Рейтинг: 0 / 0
Задача для версионника
    #32886631
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanтипа... последний раз попытаюсь объяснить что я имею в виду.

Оракл: Запись с количеством билетов обновлена, но коммит еще не сделан.
Никто не видит реального количества билетов. Всем доступно только предыдущее значение. Поэтому сказать точно сколько билетов еще можно продать - никто не может. (грязное чтение отсутствует как класс) Т.е. можно так выразиться (перефразировать) невозможно работать в реальном времени.
Все клиенты вынуждены вставать в очередь и ждать когда можно будет заблокировать запись и получить актуальное количество доступных билетов.

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

Если Вы намереваетесь использовать понятие резервирования, то отразите его в структуре данных.

Вы пытаетесь внушить нам, что механизм транзакций сервера надо использовать для моделирования понятий предметной области.
...
Рейтинг: 0 / 0
Задача для версионника
    #32886651
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Dogen
Если вы подразумеваете, что резервирование - это синоним бронирования, или эээ. предварительной продажи, то - ОК! Назовем это не резервированием, а назовем это - блокированием на время проведения транзакции. Впрочем термин можете подобрать сами. Это не изменит сути процесса.
...
Рейтинг: 0 / 0
Задача для версионника
    #32886708
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
2gardenman

опять читал 3 раза :) вы предлагаете при бронировании запускать на пару недель транзакцию с блокировкой ? я правильно понял ?
...
Рейтинг: 0 / 0
Задача для версионника
    #32886720
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yo!2gardenman

опять читал 3 раза :) вы предлагаете при бронировании запускать на пару недель транзакцию с блокировкой ? я правильно понял ?

Я больше объяснять не буду. Я лучше жестами покажу @#$!@#$ )
...
Рейтинг: 0 / 0
Задача для версионника
    #32886728
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman2 Dogen
Если вы подразумеваете, что резервирование - это синоним бронирования, или эээ. предварительной продажи, то - ОК! Назовем это не резервированием, а назовем это - блокированием на время проведения транзакции. Впрочем термин можете подобрать сами. Это не изменит сути процесса.
нет-нет
я имею в виду отметку о том что место занято - в момент начала оформления билета
это укладывается в бизнес-процесс выписки - застолбил место и давай вводить паспортные данные
бронирование - это отметка о том что на это место имеется бронь
бронь снимают за сутки и за 4 часа до поезда (может и за час, не знаю).
...
Рейтинг: 0 / 0
Задача для версионника
    #32886833
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну наконец-то я получил тот ответ, который ожидал.

Присоединяюсь к остальным: вы пытаетесь методами сервера БД решить задачу, которая должна решаться методами архитектуры системы, причем решаете извращенно как оееееей.

По-русски вам объясняю решение:
Пишете в отдельную ли таблицу, либо поле таблицы с билетами количество забронированных на оформление билетов. И все. Чтобы узнать, сколько билетов осталось, нетрудно понять, что нужно из Доступного количества отнять Забронированное количество. После того, как билет оформлен, соответственно уменьшаем цифру в Доступном и забронированном количестве. И тоже все. Вообще никаких грязных чтений, блокировок и ничего страшного.

Если вы это до сих пор понять не можете, то вашему работодателю нужно вас гнать в шею - извините уж, но это так и есть.

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32886871
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tygraНу наконец-то я получил тот ответ, который ожидал.

Присоединяюсь к остальным: вы пытаетесь методами сервера БД решить задачу, которая должна решаться методами архитектуры системы, причем решаете извращенно как оееееей.

По-русски вам объясняю решение:
Пишете в отдельную ли таблицу, либо поле таблицы с билетами количество забронированных на оформление билетов. И все. Чтобы узнать, сколько билетов осталось, нетрудно понять, что нужно из Доступного количества отнять Забронированное количество. После того, как билет оформлен, соответственно уменьшаем цифру в Доступном и забронированном количестве. И тоже все. Вообще никаких грязных чтений, блокировок и ничего страшного.

Если вы это до сих пор понять не можете, то вашему работодателю нужно вас гнать в шею - извините уж, но это так и есть.

-- Tygra's --
И это еще что. Как только появится касса, общающаяся с головной БД методами оффлайновой репликации (ну раз в полчаса, например), начнется кино - транзакции не помогают, ой-ой-ой. В МПС это, как я догадываюсь, решали путем раздачи квот на места в конкретном поезде. Но мы же про крутую современную систему говарим :))
...
Рейтинг: 0 / 0
Задача для версионника
    #32888048
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 andrushok andrushok LeXa NalBat andrushokНакладные расходы на connection не велики, про крайне мере для Oracle и MsSQL.Вы ошибаетесь. Можете сказать лишь следующее: "накладные расходы на connection не велики, про крайне мере для задач, с которыми я сталкивался на Oracle и MsSQL".Я не ошибаюсь (я так думаю, вообще-то), однако, они _дейсвительно_ не велики. Хотя и зависят от многих факторов, в частности оракл и cgi на одном сервере или нет. Я таки про cgi толкую, на не про весь спектр задач, включаюших оракл. Хотя, полностью согласен, что использовнание долгоиграющей connection может увеличить производительность."Они _дейсвительно_ не велики." Я привел вам ссылку на результат моего теста: время коннекта в 0.019 сек не велико по сравнению со временем выборки в 0.0035 сек?

"Я таки про cgi толкую, на не про весь спектр задач, включаюших оракл." Из вашего категоричного утверждения "накладные расходы на connection не велики, про крайне мере для Oracle и MsSQL" непонятно, что вы толкуете исключительно про cgi. :) Даже если это так, то все равно вы не правы, потому что на все задачи веб-программирования ваше утверждение распространить нельзя.

Сейчас наш веб-сервер отдает страницу объемом 20-60 Кб, содержащую 5-20 строк из БД, за 0.1-0.3 сек. Если бы мы не использовали persistent connectios, то на показ каждой страницы тратилось бы еще время для подключения к БД, равное 0.02 сек. То есть благодаря постоянным подключениям мы имеем выигрыш в производительности в 7-20%.
...
Рейтинг: 0 / 0
Задача для версионника
    #32888152
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый Леха Налоговый,
Мы с Вами об одном и том же толкуем. Вот тольки по разному. 0.019 сек - это много? Помойму нет. То, что мой cgi за время своей жисти переконектится 2-3 раза - проблем не вижу никаких. Пусть даже 10 раз, фигня это все - 0.2 сек. Зато даст возможность другим cgiям жить спокойно. А то, что всяки там выборки идут за 0.0 ... 001 сек, мне как-то фиолетово, все равно потеря впемени на траффике все съедает. Cgi, если их конечно правильно писать, долго жить не должны. Хотя, бывают, конечно исключения. Всяки там отложенные запросы. Такой cgi может и час пахать (на самом деле не cgi а кака-нить апликуха, а другие cgiи тольки ее статус проверяють, пашат она еще, или закончилась уже). Ну дык, это совсем другой случай.

По сему этому, Ваши попытки, доказать, что я не прав, странны однако. Опять таки я про _cgi_ говорю, а не про все веб-приложения. На виндах cgi то не очень хорошо чуйствует. Там надоть какий-то DLL (точнее их расширения, не помню). Вот они и живут в памяти, и с IIS общаются как-то. Вот там подход может быть совсем другой.

А к словам цепляться, нехорошо. Негигиенично...
...
Рейтинг: 0 / 0
Задача для версионника
    #32890215
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushok0.019 сек - это много? Помойму нет.Так ставить вопрос нельзя. Много по сравнению с чем? Много в какой ситуации, для какой задачи? Два кило яблок - это много? Сожрать в одно рыло - да, закрыть на зиму компотов - нет. И отвечать надо не так, а как я вас уже учил :) "Помойму для задач, с которыми я сталкивался, нет."

andrushokТо, что мой cgi за время своей жисти переконектится 2-3 раза - проблем не вижу никаких. Пусть даже 10 раз, фигня это все - 0.2 сек.Если мой скрипт переконнекчивался бы 10 раз за время своего выполнения, то количество серверов нам пришлось бы удваивать. :) Для моего начальства - это бабки, а не фигня. :)

andrushokпотеря впемени на траффике все съедает.Съедает что? Память, процессорное время? Если клиент (веб-броузер) задерживает апачевского ребенка, медленно читая данные, то при этом апачевский ребенок будет спать, то есть занимать память, но не процессорное время.

andrushokПо сему этому, Ваши попытки, доказать, что я не прав, странны однако.Я сказал, что вместо неверного утверждения "накладные расходы на connection не велики, про крайне мере для Oracle и MsSQL", вы можете сказать лишь "накладные расходы на connection не велики, про крайне мере для задач, с которыми я сталкивался на Oracle и MsSQL". Я не нахожу такое уточнение странным хотя бы потому, что лично у меня есть подтверждающий его пример.

andrushokОпять таки я про _cgi_ говорю, а не про все веб-приложения.Я полагал, что "cgi-программирование" и "веб-пограммирование" - одно и то же. Объясните пожалуйста разницу.

andrushokА к словам цепляться, нехорошо. Негигиенично...О цеплянии к словам vs точности формулировок я как-то рассказал анекдот. :)

P.S.: К налоговому ведомству отношения не имею.
...
Рейтинг: 0 / 0
Задача для версионника
    #32890275
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Леха Ватный (если Налоговый не нравится - извините)
Я так думаю, разговор заходит в тупик - для Вас 0.019 сек много, для меня нет. Спорить тут уже бессмысленно. Вы можете дать пример Вашего web, где сие критично? Я могу - сюды пожалста . Кстати - для ликбеза - сие произведение программиского искуйства (я не скромен, а?) в основном наваено на ColdFusion - что к CGI технологии не имеет никакого отношения. Хотя cgiи там все-же есть, их время от времени и жаба дергает, и на прямую из HTML и JavaScript для некоторых целей вызывают. Но их там мало, да и чужеродны они там. Я думаю - это web приложение. И _почти_ без CGI. Если постораться, можно найти и _совсем_ без CGI.

Ну если Вам так угодно, я могу согласиться, что только, с теми, к какими я сталкивался. Мир велик, и я за все программы не в ответе.

Ну шо, мир, или бум дальше пиписками мериться?
...
Рейтинг: 0 / 0
Задача для версионника
    #32890310
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushokВы можете дать пример Вашего web, где сие критично?price.ru

andrushokНу если Вам так угодно, я могу согласиться, что только, с теми, к какими я сталкивался.Иейс! (Как сказал бы мальчик, который "один дома".) Теперь с этим вашим утверждением смог бы поспорить только программист, столкнувшийся с тем же проектом что и вы, и обнарувший, что в этом проекте "расходы на connection не малы по сравнению с другими расходами". :)

andrushokНу шо, мир, или бум дальше пиписками мериться?Не будем уподобляться Беклемишеву. :)
...
Рейтинг: 0 / 0
Задача для версионника
    #32890387
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну шо, посмотрел я Вашу price. Так, шустро работает. Правда, HTML простой, как сибирский валенок. Ни те фреймов, ни DHTML, ни JavaScript, ни какой жабы конечно (может иде есть, везде не лазил). Конечно, еще с Macа интерестно залесть, как оно там под Camino например пашет, или (упоси Господь) под маковский IE. Вот тольки вопросик, а чой то за скриты таки хитрые либо без расширения, либо с html (?) расширением

Код: plaintext
1.
2.
href="/bin/price/get?_url_=http%3A%2F%2Fwww.price.ru%2Fclub%2Fclub.html%3Fwhere%3D00%26base%3D1&_item_=discount2.gif&where=00&_owner_=9921&base=1"
HREF="/about/lang.html?where=00&base=1"

Интерестна, а?

Кстати, а Вы согластны, что есть некоторые приложения, иде время connection особой роли не играет?
...
Рейтинг: 0 / 0
Задача для версионника
    #32890408
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushokПравда, HTML простой, как сибирский валенок.Видимо усложнение хтмл-я не является целью нашего вебмастера. :) Лично я с этим согласен.

andrushokНи те фреймов, ни DHTML, ни JavaScript, ни какой жабы конечно (может иде есть, везде не лазил).По-моему из этого используется только немного джаваскрипта.

andrushokВот тольки вопросик, а чой то за скриты таки хитрые либо без расширенияВроде бы в конфиге апача несложно определить обработчик для расширения или директории. Мы используем мод_перл.

andrushokКстати, а Вы согластны, что есть некоторые приложения, иде время connection особой роли не играет?Конечно. :)
...
Рейтинг: 0 / 0
Задача для версионника
    #32890459
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леха Ватный
Видимо усложнение хтмл-я не является целью нашего вебмастера. :) Лично я с этим согласен.


Я тоже, не люблю наворотов. Можете радоваться, что вам (Вам и вашему веб мастеру) позволена така роскошь

Леха Ватный
По-моему из этого используется только немного джаваскрипта.


Ну без него воще тяжело. Рас мало, вот и не нашел. Правильной дорогой идете, товарищи...

Леха Ватный
Вроде бы в конфиге апача несложно определить обработчик для расширения или директории. Мы используем мод_перл.


И совсем не "вроде бы". Есть там некий AddHandler который это все отпахивает. Я се про расщирения. Ну и с директориями там усе тип-топ. Вот тольки зачем html у перлового скрипта иметь - непонятно. Наверно, чоб враги не догадались! Я ничого супротив не имею... Хоть xxx ставте, любителей порнухи дразнить что бы.
...
Рейтинг: 0 / 0
Задача для версионника
    #32890528
Фотография Лох Позорный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBatНе будем уподобляться Беклемишеву. :)
Билят, везде физтехи?

Сорь за оффтоп
...
Рейтинг: 0 / 0
Задача для версионника
    #32890732
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushokВот тольки зачем html у перлового скрипта иметь - непонятно.Вроде бы мы так и не делаем. Это - хтмл с мод-перловыми вставками, это - скрипт.

Лох ПозорныйБилят, везде физтехи?Только с разной плотностью. :)
...
Рейтинг: 0 / 0
Задача для версионника
    #32893383
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, Леха, еще один мумент. Ваше творение никак не предполагает активного участия юзерей. Может, я что-то и не раскопал, копал не глубоко - сознаюсь. Но совсем не похоже, что есть воще кака-нить транзакция, кады я например, зашел туды. Так, сплошной SELECT. Для меня, как для конечного пользователя - сия база ReadOnly - я там ничего не меняю. Ну а кады кажный юзверь, сволочь така, норовит чо-нить в базе напортить, INSERT с UPDATE всяки шлет - подход может быть совсем другой,
...
Рейтинг: 0 / 0
Задача для версионника
    #32894624
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПишете в отдельную ли таблицу, либо поле таблицы с билетами количество забронированных на оформление билетов. И все. Чтобы узнать, сколько билетов осталось, нетрудно понять, что нужно из Доступного количества отнять Забронированное количество. После того, как билет оформлен, соответственно уменьшаем цифру в Доступном и забронированном количестве. И тоже все. Вообще никаких грязных чтений, блокировок и ничего страшного.
А если задачу усложнить. Допустим решается задача складского учета. Списывается товар со склада. Причем при списании нужно узнать учетную (себестоимость) цену товара расчитываемую по методу ФИФО, ЛИФО или средних. При этом возможны правки "задним" числом.
Опять же используется дополнительная таблица хранящая остатки в учетных ценах для каждой строчки документа. Ну например для Накладной №5 строчка 3 списывается 5 банок огурцов, из них 3 приходили по 10руб, а 2 по 5 руб. В MSSQL тут без блокировок ни как, так как при правке задним число все может поменяться то есть допустим стать 5 банок по 4 рубля.
А как в Oracle? Я так понимаю требуется совершенно другая архитектура.
Вопрос задан сугубо из познавательных целей, в Oracle я полный профан.
...
Рейтинг: 0 / 0
Задача для версионника
    #32894651
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Crip авторПишете в отдельную ли таблицу, либо поле таблицы с билетами количество забронированных на оформление билетов. И все. Чтобы узнать, сколько билетов осталось, нетрудно понять, что нужно из Доступного количества отнять Забронированное количество. После того, как билет оформлен, соответственно уменьшаем цифру в Доступном и забронированном количестве. И тоже все. Вообще никаких грязных чтений, блокировок и ничего страшного.
А если задачу усложнить. Допустим решается задача складского учета. Списывается товар со склада. Причем при списании нужно узнать учетную (себестоимость) цену товара расчитываемую по методу ФИФО, ЛИФО или средних. При этом возможны правки "задним" числом.
Опять же используется дополнительная таблица хранящая остатки в учетных ценах для каждой строчки документа. Ну например для Накладной №5 строчка 3 списывается 5 банок огурцов, из них 3 приходили по 10руб, а 2 по 5 руб. В MSSQL тут без блокировок ни как, так как при правке задним число все может поменяться то есть допустим стать 5 банок по 4 рубля.
А как в Oracle? Я так понимаю требуется совершенно другая архитектура.
Вопрос задан сугубо из познавательных целей, в Oracle я полный профан.

Какая разница, какая у СУБД архитектура?..

Скорее всего Вам придется озаботиться каскадным пересчетом себестоимостей в документах.

Остатки в учетных ценах - это не предмет для продажи, т.к. учетные цены в Вашей модели могут в любой момент измениться. А вот количественные остатки по партиям товара - это да.

Кстати, Вы их автоматически рассчитывать будете или дадите возможность выбрать партии товара вручную? Цены на них надо иметь разные, но "ценообразование в онлайне" имхо вещь довольно-таки ненужная.

По моему мнению, архитектура такой системы сильно зависит от бизнес-процесса. Если же Вы собираетесь делать тиражируемое решение, то объем работ будет очень большой.
...
Рейтинг: 0 / 0
Задача для версионника
    #32894711
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПо моему мнению, архитектура такой системы сильно зависит от бизнес-процесса. Если же Вы собираетесь делать тиражируемое решение, то объем работ будет очень большой
Ну это я и сам знаю. В данном случае шла речь только о автоматическом формировании партий, а зачем это бизнесу вопрос не стоял. Просто хотелось услышать как решается вопрос поддержания целостности данных при такой постановке задачи в Oracle.
...
Рейтинг: 0 / 0
Задача для версионника
    #32894727
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Crip авторПо моему мнению, архитектура такой системы сильно зависит от бизнес-процесса. Если же Вы собираетесь делать тиражируемое решение, то объем работ будет очень большой
Ну это я и сам знаю. В данном случае шла речь только о автоматическом формировании партий, а зачем это бизнесу вопрос не стоял. Просто хотелось услышать как решается вопрос поддержания целостности данных при такой постановке задачи в Oracle.

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

Если я не прав, то о какой целостности идет речь???
...
Рейтинг: 0 / 0
Задача для версионника
    #32894738
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
>А как в Oracle? Я так понимаю требуется совершенно другая архитектура.

получить блокируещее чтение в оракле можно через select ... for update
...
Рейтинг: 0 / 0
Задача для версионника
    #32894863
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторУ меня возникло такое впечатление, что Вы решили цену банки сделать составной частью первичного ключа партии товара
Хм... Это был всего лишь пример. Первичным ключом партии, если это можно так назвать, в данном случае является ID строки документа прихода... Хотя это тоже упрощенный подход.

авторполучить блокируещее чтение в оракле можно через select ... for update
То бишь блокировки в Oracle все же есть и при случае их можно применить?
...
Рейтинг: 0 / 0
Задача для версионника
    #32894871
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrushokДа, Леха, еще один мумент. Ваше творение никак не предполагает активного участия юзерей. Может, я что-то и не раскопал, копал не глубоко - сознаюсь. Но совсем не похоже, что есть воще кака-нить транзакция, кады я например, зашел туды. Так, сплошной SELECT. Для меня, как для конечного пользователя - сия база ReadOnly - я там ничего не меняю.Да, у нас транзакций мало-мало. Подавляющая часть запросов - select.

andrushokНу а кады кажный юзверь, сволочь така, норовит чо-нить в базе напортить, INSERT с UPDATE всяки шлет - подход может быть совсем другой,Думаю, да. Но может быть и для этой задачи попробовать, как вам советовали, commit или application server.
...
Рейтинг: 0 / 0
Задача для версионника
    #32894922
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
>То бишь блокировки в Oracle все же есть и при случае их можно применить?

да.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SQL*Plus: Release  9 . 2 . 0 . 4 . 0  - Production on Ot Feb  1   14 : 21 : 52   2005 

Copyright (c)  1982 ,  2002 , Oracle Corporation.  All rights reserved.

Enter password: *******

Connected to:
Oracle9i Enterprise Edition Release  9 . 2 . 0 . 4 . 0  - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release  9 . 2 . 0 . 4 . 0  - Production


Session altered.

SQL>  select txt from test for update nowait ;
 select txt from test for update nowait
                 *
ERROR at line  1 :
ORA- 00054 : resource busy and acquire with NOWAIT specified


SQL>  select txt from test for update wait  5  ;
 select txt from test for update wait  5 
                 *
ERROR at line  1 :
ORA- 30006 : resource busy; acquire with WAIT timeout expired

...
Рейтинг: 0 / 0
Задача для версионника
    #32894983
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понятненько. Хотя я думаю, что для моего примера не подойдет. В MSSQL в случае блокировки остальные сессии просто ожидают ее снятия...
...
Рейтинг: 0 / 0
Задача для версионника
    #32895013
Yo!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Yo!
Гость
ну тогда не у казывайте nowait и будет он ждать вечно ... но подождать минуту wait 60 имхо правильней.
...
Рейтинг: 0 / 0
Задача для версионника
    #32895203
Фотография tygra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, циску меняли, выпал :))

авторВ MSSQL тут без блокировок ни как, так как при правке задним число все может поменяться то есть допустим стать 5 банок по 4 рубля.
А смысл в блокировке? Чтобы никто не смог прочитать накладную, пока вы ее меняете задним числом? Ну так... Это вообще зависит от архитектуры. И от конкретной ситуации. Если к накладным обращаются ежесекундно, а внесли сейчас неправильно, а нужно чтобы сейчас уже было правильно , тогда наверное стоит ставить блокировку. А если накладная была введена месяц назад например, то какой смысл в блокировке - от кого? Все, кто мог, уже накладную "поиспользовали", и ничего не изменится от того, поправите вы в 16.45 или 16.55 с блокировкой или без - прошло уже очень много времени, чтобы думать о таких мелких вещах, как блокировка :))

-- Tygra's --
...
Рейтинг: 0 / 0
Задача для версионника
    #32895416
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2tygra
Так изменение одной накладной подразумевает каскадное изменение таблицы остатков, при этом другие пользователи также эту таблицу обновляют...
...
Рейтинг: 0 / 0
Задача для версионника
    #32895421
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗЫ:
Вообще задача конечно бессмысленная и на практике трудновыполнимая, потому как конкуренция возрастает не по детски. Но что поделать если бизнес так потребовал, а прошибить их медные лбы не получается?
...
Рейтинг: 0 / 0
Задача для версионника
    #32895457
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Crip2tygra
Так изменение одной накладной подразумевает каскадное изменение таблицы остатков, при этом другие пользователи также эту таблицу обновляют...

Сколько документов изменять будете, столько раз и текущие остатки пересчитаете. Не вижу никаких логических проблем.

Естественно, обновлять надо с блокировкой записей об остатках - ну так select for update вам должно помогать, нет? Вообще можно это на последовательных транзакциях сделать, если делать все быстро то никто и не заметит.
...
Рейтинг: 0 / 0
Задача для версионника
    #32895506
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Dogen
Все так если закрывать период достаточно часто, а вот если какой-нибудь сумасшедший юзер захочет поменять что-то в начале квартала, то все остальные будут считать ворон...
...
Рейтинг: 0 / 0
Задача для версионника
    #32895563
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это ничего если я вмешаюсь?
Обычно я вот так вот (буду в синтаксисе оракла писать) :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
DECLARE Saldo_ numeric;
BEGIN
   SELECT Saldo INTO Saldo_ FROM ACCOUNT WHERE .... FOR UPDATE;
   Savdo_:=Saldo_ + <Какая-то сумма>
   UPDATE ACCOUT SET Saldo=Saldo_ WHERE ....;
   COMMIT;
END;
/

не делаю, делаю проще:
Код: plaintext
1.
2.
UPDATE ACCOUT SET Saldo=Saldo_ + <какая-то сумма> WHERE ....;
COMMIT;
При этом абсолютно пофиг какой уровень изоляции или режим выполнения транзакций установлены. Все равно, перед внесением изменений запись сначала заблокируется. В сущности я ниже написал то же что и выше, тока короче. Единственное что в Оракле нужно делать явно - так это COMMIT.
Аналогичная ситуация в DB2. (в DB2 и в Oracle транзакции начинаются неявно, но завершаются всегда явно, - типа промышленные субд все-таки).
А вот в MSSQL, Sybase, если явно не сказал BEGIN TRAN, то и COMMIT делать не обязательно, потому как всякая операция там - атомарна. Поэтому можно просто бахнуть:
Код: plaintext
1.
UPDATE ACCOUT SET Saldo=Saldo_ + @<какая-то переменная> WHERE ....
В любом случае перед такой операцией нужная запись будет блакирована, обновлена, и разблокирована. И никаких катаклизмов не случится. И никаких потерянных изменений. И ничего повторно считывать не надо. И абсолютно пофиг какой уровень изоляции.

Несколько хуже обстоят дела у Оракла с курсорами. Я так полагаю держать долго открытый курсор там не рекомендуется. Вообще-то я еще не пробил этот вопрос. Если кто знает, то может скажет, нарвусь ли я на ORA-01555 в том случае если в одной сессии просто открою курсор выберу 1 запись (коммит не делаю), а затем открываю другую сессию, делаю кучу изменений, а затем начну фетчить открытым курсором в первой сессии? На вскидку скажу что для блокировочника обсолютно пофиг как долго будет держаться курсор открытым.
...
Рейтинг: 0 / 0
Задача для версионника
    #32895577
Фотография Dogen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanЭто ничего если я вмешаюсь?
Обычно я вот так вот (буду в синтаксисе оракла писать) :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
DECLARE Saldo_ numeric;
BEGIN
   SELECT Saldo INTO Saldo_ FROM ACCOUNT WHERE .... FOR UPDATE;
   Savdo_:=Saldo_ + <Какая-то сумма>
   UPDATE ACCOUT SET Saldo=Saldo_ WHERE ....;
   COMMIT;
END;
/

не делаю, делаю проще:
Код: plaintext
1.
2.
UPDATE ACCOUT SET Saldo=Saldo_ + <какая-то сумма> WHERE ....;
COMMIT;
При этом абсолютно пофиг какой уровень изоляции или режим выполнения транзакций установлены. Все равно, перед внесением изменений запись сначала заблокируется. В сущности я ниже написал то же что и выше, тока короче. Единственное что в Оракле нужно делать явно - так это COMMIT.
Аналогичная ситуация в DB2. (в DB2 и в Oracle транзакции начинаются неявно, но завершаются всегда явно, - типа промышленные субд все-таки).
А вот в MSSQL, Sybase, если явно не сказал BEGIN TRAN, то и COMMIT делать не обязательно, потому как всякая операция там - атомарна. Поэтому можно просто бахнуть:
Код: plaintext
1.
UPDATE ACCOUT SET Saldo=Saldo_ + @<какая-то переменная> WHERE ....
В любом случае перед такой операцией нужная запись будет блакирована, обновлена, и разблокирована. И никаких катаклизмов не случится. И никаких потерянных изменений. И ничего повторно считывать не надо. И абсолютно пофиг какой уровень изоляции.

Я охреневаю и умолкаю Живите в своем мире DIRTY READ.
...
Рейтинг: 0 / 0
Задача для версионника
    #32895834
Фотография andrushok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Леха
Commit конечно транзакцию закрывает, это правда. А вот сессию (connection) зачем тады держать, если программа просто считать начинает. Лучше отпустить, пусть другие попользуются. Одно дело, кады все _расчеты_ в БД делаются, совсем другое - когда на стороне...
...
Рейтинг: 0 / 0
123 сообщений из 123, показаны все 5 страниц
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Задача для версионника
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]