Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Почему-то не происходит rollback / 5 сообщений из 5, страница 1 из 1
13.12.2008, 19:37
    #35712743
JetAlex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему-то не происходит rollback
Есть ASA 8.0.2
хранимой процедуре (см. ниже)
не происход откат транзакции почему-то,
что надо подправить?


Код: 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.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
ALTER procedure dba.INSERT_RASHOD_DETAIL(@IN_ID_TYPE_REMONT integer,@IN_NAME_REMONT varchar( 254 ),@IN_ID_CAR integer,@IN_GOS_NOMER varchar( 20 ),@IN_DATA date,@IN_NAME_VID_REMONT varchar( 20 ),@IN_VID_REMONT integer,@IN_ID_MEN integer,@IN_NAME1 varchar( 30 ),@IN_ID_OTDEL integer,@IN_NAME_OTDEL varchar( 100 ),@IN_ID_PERSON integer,@IN_MATERIAL_PERSON varchar( 30 ),@IN_ID_USER integer,@IN_ID_REMONT_LIST integer)
as
declare @i smallint,
@IN_KOLVO_DETAIL real,
@IN_ID_PRIHOD_LIST_DETAIL integer,
@FLAG varchar( 5 ),
@IN_OSTATOK real,
@IN_ID_DETAIL integer,
@IN_ID_REMONT integer,
@IN_ID_REMONT_WORK integer,
@IN_ID_REMONT_LIST_DETAIL INTEGER,
@IN_ID_DETAIL_SKLAD INTEGER,
@IN_OSTATOK_SKLAD REAL,
@IN_ID_REMONT_SPIS INTEGER,
@sp char( 2 )

/**/
/**/
/**/
/**/

/**/
/**/
begin transaction
select @FLAG='0'

/**/
/**/
/**/
select @IN_ID_REMONT=- 1 
/**/
/**/
if @IN_ID_REMONT_LIST >  0  begin
    select @IN_ID_REMONT = MAX(ID_REMONT) from
      REMONT_LIST where
      ID_REMONT_LIST = @IN_ID_REMONT_LIST
  end
/**/
/**/
/**/
/**/
/**/
if(@IN_ID_REMONT = - 1 ) or(@IN_ID_REMONT is null) begin
    insert into REMONT(START_DATA,
      END_DATA,
      ID_CAR,
      GOS_NOMER,
      NAME_VID_REMONT,
      VID_REMONT,
      ID_MEN,
      NAME1,
      ID_OTDEL,
      NAME_OTDEL,
      ID_PERSON,
      MATERIAL_PERSON) values(
      @IN_DATA,
      @IN_DATA,
      @IN_ID_CAR,
      @IN_GOS_NOMER,
      @IN_NAME_VID_REMONT,
      @IN_VID_REMONT,
      @IN_ID_MEN,
      @IN_NAME1,
      @IN_ID_OTDEL,
      @IN_NAME_OTDEL,
      @IN_ID_PERSON,
      @IN_MATERIAL_PERSON)
    select @IN_ID_REMONT=@@IDENTITY
    if @@error<> 0  begin 
        select @FLAG='2' 
        goto ERR1
    end
     
     /**/
    /**/
    /**/
    /**/
    /**/
    /**/
    /**/  
    if @IN_ID_REMONT_LIST >  0  begin
        update REMONT_LIST set
          ID_REMONT = @IN_ID_REMONT where
          ID_REMONT_LIST = @IN_ID_REMONT_LIST
        if @@error<> 0  begin 
          select @FLAG='2' 
          goto ERR1
        end
        
      end

 //else begin
//          select @FLAG='2'
//          goto ERR1
 end
/**/
/**/
/**/
/**/
  insert into REMONT_SPIS_DETAILS
    (DATA_SPIS,
     ID_MEN,
     NAME1,
     ID_PERSON,
     MATERIAL_PERSON,
     ID_REMONT)
    VALUES
     (@IN_DATA,
      @IN_ID_MEN,
      @IN_NAME1,
      @IN_ID_PERSON,
      @IN_MATERIAL_PERSON,
      @IN_ID_REMONT)
     select @IN_ID_REMONT_SPIS=@@IDENTITY
    if @@error<> 0  begin 
        select @FLAG='2' 
        goto ERR1
    end
    /**/
/**/
/**/
/**/
/**/
  select @IN_ID_REMONT_WORK=- 1 
/**/ 
  select @IN_ID_REMONT_WORK=(SELECT ID_REMONT_WORK
                          FROM REMONT_WORK
                          WHERE ID_REMONT=@IN_ID_REMONT
                          AND ID_TYPE_REMONT=@IN_ID_TYPE_REMONT)
/**/
/**/
/**/

IF (@IN_ID_REMONT_WORK= 1 ) OR (@IN_ID_REMONT_WORK IS NULL) BEGIN
insert into REMONT_WORK(ID_TYPE_REMONT,
  NAME_REMONT,
  TIME_REMONT,
  ID_REMONT) values(
  @IN_ID_TYPE_REMONT,
  @IN_NAME_REMONT,
   0 ,
  @IN_ID_REMONT)
select @IN_ID_REMONT_WORK=@@IDENTITY
if @@error<> 0  begin 
       select @FLAG='2' 
        goto ERR1
end

//else begin
//          select @FLAG='2'
//          goto ERR1
end
--    
--
--
/**/
select @i = count(*) from
  REMONT_LIST_DETAILS
where
    ID_USER = @IN_ID_USER
/**/
/**/
declare cur dynamic scroll cursor for select KOLVO_DETAIL,
    ID_PRIHOD_LIST_DETAIL,
    ID_DETAIL,
    ID_DETAIL_SKLAD from
    REMONT_LIST_DETAILS where
    ID_USER = @IN_ID_USER
    
open cur
fetch next cur into @IN_KOLVO_DETAIL,
  @IN_ID_PRIHOD_LIST_DETAIL,
  @IN_ID_DETAIL,
  @IN_ID_DETAIL_SKLAD
while @i >  0 
  begin
    /**/
    /**/
    /**/
    /**/
    /**/
    select @IN_KOLVO_DETAIL=ROUND(ROUND(@IN_KOLVO_DETAIL, 3 ), 2 )
    /**/
    /**/
    IF (@IN_ID_DETAIL_SKLAD= 0 ) OR (@IN_ID_DETAIL_SKLAD IS NULL) BEGIN
    /**/
       select @IN_OSTATOK =ROUND(ROUND(OSTATOK, 3 ), 2 ) from
         PRIHOD_LIST_DETAIL where
         ID_PRIHOD_LIST_DETAIL = @IN_ID_PRIHOD_LIST_DETAIL
    /**/
    /**/
    /**/
    /**/
       if @IN_OSTATOK >= @IN_KOLVO_DETAIL begin
          update PRIHOD_LIST_DETAIL set
            OSTATOK = @IN_OSTATOK-@IN_KOLVO_DETAIL where
            ID_PRIHOD_LIST_DETAIL = @IN_ID_PRIHOD_LIST_DETAIL
        --
        --
        if @@error<> 0  begin 
         select @FLAG='2' 
         goto ERR1
        end
        --
        --
          update DETAILS set
            OSTATOK = OSTATOK-@IN_KOLVO_DETAIL where
            ID_DETAIL = @IN_ID_DETAIL
         if @@error<> 0  begin 
          select @FLAG='2' 
          goto ERR1
         end  
        end
       else begin
          select @FLAG='1'
          goto ERR1
       end
    end
    --
    --
    else begin
       select @IN_OSTATOK =ROUND(ROUND(OSTATOK, 3 ), 2 ) from
         PRIHOD_LIST_DETAIL_SKLAD where
         ID_DETAIL_SKLAD = @IN_ID_DETAIL_SKLAD
       /**/
       /**/
       /**/
        if @IN_OSTATOK >= @IN_KOLVO_DETAIL begin
          update PRIHOD_LIST_DETAIL_SKLAD set
            OSTATOK = @IN_OSTATOK-@IN_KOLVO_DETAIL where
            ID_DETAIL_SKLAD = @IN_ID_DETAIL_SKLAD
           
          if @@error<> 0  begin 
           select @FLAG='2' 
           goto ERR1
          end 
        end
       else begin
          select @FLAG='1'
          goto ERR1
       end
    end
    /**/
    /**/
    /**/
    /**/
    /**/
    /**/
    /**/
    /**/
    select @i=@i- 1 
    fetch next cur into @IN_KOLVO_DETAIL,
      @IN_ID_PRIHOD_LIST_DETAIL,@IN_ID_DETAIL,@IN_ID_DETAIL_SKLAD end
close cur
/**/
/**/
/**/
insert into REMONT_DETAILS(ID_DETAIL,
  NAME_DETAIL,
  KOD_DETAIL,
  KOLVO_DETAIL,
  PRICE_DETAIL,
  SUMMA_DETAIL,
  ID_PRIHOD_LIST_DETAIL,
  ID_REMONT_WORK,
  ID_REMONT_LIST,
  ID_REMONT_LIST_DETAIL,
  ID_DETAIL_SKLAD,
  ID_REMONT_SPIS)(
  select ID_DETAIL,
    NAME_DETAIL,
    KOD_DETAIL,
    KOLVO_DETAIL,
    PRICE_DETAIL,
    SUMMA_DETAIL,
    ID_PRIHOD_LIST_DETAIL,
    @IN_ID_REMONT_WORK,
    @IN_ID_REMONT_LIST,
    ID_REMONT_LIST_DETAIL,
    @IN_ID_DETAIL_SKLAD,
    @IN_ID_REMONT_SPIS from
    REMONT_LIST_DETAILS where
    ID_USER = @IN_ID_USER)
  if @@error<> 0  begin 
        select @FLAG='2' 
        goto ERR1
  end
/**/
/**/
/**/
/**/
delete from
  REMONT_LIST_DETAILS
where
    ID_USER = @IN_ID_USER
/**/
/**/
/**/
err1: if @FLAG <> '0' begin
    print 'rollback'
    select @FLAG
    rollback transaction  
  end
else
  begin
    print 'commit'
    select @FLAG
    commit transaction
  end
select @FLAG
return @FLAG
//end
...
Рейтинг: 0 / 0
15.12.2008, 14:14
    #35714644
Alexandr Nikolaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему-то не происходит rollback
from BOL Every SQL statement resets @@error , so the status check must immediately follow the statement whose success is in question. from BOLTransact-SQL uses the SELECT statement to assign values to local variablesJetAlex
Код: plaintext
1.
2.
3.
4.
5.
6.
...
select @IN_ID_REMONT=@@IDENTITY
if @@error<> 0  begin 
  select @FLAG='2' 
  goto ERR1
end
...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
declare @error_local integer
select @error_local =  0 
...
select @@error, @@IDENTITY into @error_local, @IN_ID_REMONT
if (@error_local <>  0 )
begin 
  select @FLAG='2' 
  goto ERR1
end
...

C уважением,
AlexandrN©
...
Рейтинг: 0 / 0
15.12.2008, 19:02
    #35715558
JetAlex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему-то не происходит rollback
Убрал SELECT @FLAG

err1: if @FLAG <> '0' begin
print 'rollback'
select @FLAG
rollback transaction
end

И заработало...
Вопрос снят.
...
Рейтинг: 0 / 0
15.12.2008, 20:01
    #35715654
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему-то не происходит rollback
Вообще-то, очень и очень не рекомендуется управлять транзакциями изнутри хранимой процедуры.
ROLLBACK и COMMIT не симметричны. ROLLBACK откатывает транзакции всех уровней вложенности, а COMMIT закрывает только свой уровень.
Это значит, что если ты начнешь транзакцию до вызова ХП, сделаешь какой-то апдейт базы. Потом позовешь ХП внутри которой начнешь еще одну транзакцию, сделаешь там второе изменение, а потом откатишь. То откатятся оба изменения. И то которое ты сделал внутри ХП и то которое было до ХП.
Вот пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
create table t (i integer, c char( 1 ))
go
create procedure p
as
  begin transaction
  insert into t values( 100 , 'z')
  rollback
go

begin transaction
insert into t values( 1 , 'a')
execute p
insert into t values( 2 , 'b')
commit
go
select * from t
go


В ASA для отката только изменений сделаных внутри ХП существует специальный механизм: SAVEPOINT / ROLLBACK TO SAVEPOINT. Вот им и надо пользоваться, он не нарушит внешнее по отношению к ХП управление транзакциями.
...
Рейтинг: 0 / 0
15.12.2008, 20:06
    #35715660
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему-то не происходит rollback
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create table t (i integer, c char( 1 ))
go
create procedure p
as
  begin transaction
  insert into t values( 100 , 'z')
  commit
go

begin transaction
insert into t values( 1 , 'a')
execute p
rollback
insert into t values( 2 , 'b')
commit
go
select * from t
go
Почти тот же самый пример что и в предыдущем посте, только тут ХП вроде бы коммитит свои изменения. Но внешний rollback с легкостью их отменяет.
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Почему-то не происходит rollback / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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