powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Транзакции
8 сообщений из 8, страница 1 из 1
Транзакции
    #33778422
Valerii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ, я бы уверен что оборачиваю критические процессы обновления таблиц правильно, но вот нарвался на проблему, которая заставила взглянуть по-другому на эти вещи.

Решение конечно найдено, но кто подскажет как правильно обернуть процесс обновления трех таблиц Table1, Table2, Table3 транзакцией, что в случае какого-нибудь сбоя, все изменения в этих трех таблицах, будут откатаны...
Втт примерно мой подход:
Кнопка, на ней 2 метода
Click()
Код: 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.
BEGIN TRANSACTION

		If ThisForm.Noerror = .F.
			INSERT INTO TABLE1 VALUE (1,'Text1')
			INSERT INTO TABLE1 VALUE (2,'Text2')
			INSERT INTO TABLE1 VALUE (3,'Text3')
			INSERT INTO TABLE1 VALUE (4,'Text4')
			INSERT INTO TABLE1 VALUE (5,'Text5')
			INSERT INTO TABLE1 VALUE (6,'Text6')
				SELECT Table1
				=TableUpdate(.T.)
		ENDIF

		If ThisForm.Noerror = .F.
			INSERT INTO TABLE2 VALUE (1,'Text1')
			INSERT INTO TABLE2 VALUE (2,'Text2')
			INSERT INTO TABLE2 VALUE (3,'Text3')
			INSERT INTO TABLE2 VALUE (4,'Text4')
			INSERT INTO TABLE2 VALUE (5,'Text5')
			INSERT INTO TABLE2 VALUE (6,'Text6')
				SELECT Table2
				=TableUpdate(.T.)
		ENDIF

		a = b * k && Генерим ошибку ... - такие переменные оказались не определены...

		If ThisForm.Noerror = .F.
			INSERT INTO TABLE3 VALUE (1,'Text1')
			INSERT INTO TABLE3 VALUE (2,'Text2')
			INSERT INTO TABLE3 VALUE (3,'Text3')
			INSERT INTO TABLE3 VALUE (4,'Text4')
			INSERT INTO TABLE3 VALUE (5,'Text5')
			INSERT INTO TABLE3 VALUE (6,'Text6')
				SELECT Table3
				=TableUpdate(.T.)
		ENDIF

IF ThisForm.Noerror = .F.
	END TRANSACTION
ENDIF

 Метод Error() 
LPARAMETERS nError, cMethod, nLine
Wait window str(TXNLEVEL())+' ' +STR(nError)

DO WHILE  TXNLEVEL() >= 1
	ROLLBACK
ENDDO	

THISFORM.NoError = .T.

SELECT Table1
=TableRevert(.T.)
SELECT Table2
=TableRevert(.T.)
SELECT Table3
=TableRevert(.T.)
...
Рейтинг: 0 / 0
Транзакции
    #33778587
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
LOCAL llSuccess
llSuccess = .T.
BEGIN TRANSACTION
IF m.llSuccess = .T.
	* Модификация первой таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table1")
ENDIF
IF m.llSuccess = .T.
	* Модификация второй таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table2")
ENDIF
IF m.llSuccess = .T.
	* Модификация третьей таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table3")
ENDIF

IF m.llSuccess = .T.
	END TRANSACTION
ELSE
	ROLLBACK
ENDIF

В случае неудачи, команда TableUpdate() - НЕ выбрасывает сообщение об ошибке. Она просто возвращает .F. Молча. Без визуальных спец.эффектов.

В буферизированной таблице команды вставки INSERT-SQL, как правило, также не генерят ошибок, поскольку не отрабатывают триггера на вставку. Хотя, конечно, отработают RULE и DEFAULT, но как-то сомнительно, что будут вставляться заведомо некорректные данные.

ROLLBACK откатит буфер таблиц в то состояние, которое было на момент подачи команды BEGIN TRANSACTION. Поэтому, дополнительный откат буфера по TableRevert() обычно не нужен (хотя и не помешает. Были глюки с буферами в подобных ситуациях)

Таким образом, событие Error(), скорее всего, вообще не отработает. Даже если в процессе сохранния будут ошибки.
...
Рейтинг: 0 / 0
Транзакции
    #33779217
Valerii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
LOCAL llSuccess
llSuccess = .T.
BEGIN TRANSACTION
IF m.llSuccess = .T.
	* Модификация первой таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table1")
ENDIF
IF m.llSuccess = .T.
	* Модификация второй таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table2")
ENDIF
IF m.llSuccess = .T.
	* Модификация третьей таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table3")
ENDIF

IF m.llSuccess = .T.
	END TRANSACTION
ELSE
	ROLLBACK
ENDIF

В случае неудачи, команда TableUpdate() - НЕ выбрасывает сообщение об ошибке. Она просто возвращает .F. Молча. Без визуальных спец.эффектов.

В буферизированной таблице команды вставки INSERT-SQL, как правило, также не генерят ошибок, поскольку не отрабатывают триггера на вставку. Хотя, конечно, отработают RULE и DEFAULT, но как-то сомнительно, что будут вставляться заведомо некорректные данные.

ROLLBACK откатит буфер таблиц в то состояние, которое было на момент подачи команды BEGIN TRANSACTION. Поэтому, дополнительный откат буфера по TableRevert() обычно не нужен (хотя и не помешает. Были глюки с буферами в подобных ситуациях)

Таким образом, событие Error(), скорее всего, вообще не отработает. Даже если в процессе сохранния будут ошибки.


Поэтому, дополнительный откат буфера по TableRevert() обычно не нужен (хотя и не помешает. Были глюки с буферами в подобных ситуациях)
Именно вот это у меня и произошло......
...
Рейтинг: 0 / 0
Транзакции
    #33779229
Valerii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valerii[quot ВладимирМ]
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
LOCAL llSuccess
llSuccess = .T.
BEGIN TRANSACTION
IF m.llSuccess = .T.
	* Модификация первой таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table1")
ENDIF
IF m.llSuccess = .T.
	* Модификация второй таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table2")
ENDIF
IF m.llSuccess = .T.
	* Модификация третьей таблицы
	m.llSuccess = TableUpdate(.T.,.T.,"Table3")
ENDIF

IF m.llSuccess = .T.
	END TRANSACTION
ELSE
	ROLLBACK
ENDIF

В случае неудачи, команда TableUpdate() - НЕ выбрасывает сообщение об ошибке. Она просто возвращает .F. Молча. Без визуальных спец.эффектов.

В буферизированной таблице команды вставки INSERT-SQL, как правило, также не генерят ошибок, поскольку не отрабатывают триггера на вставку. Хотя, конечно, отработают RULE и DEFAULT, но как-то сомнительно, что будут вставляться заведомо некорректные данные.

ROLLBACK откатит буфер таблиц в то состояние, которое было на момент подачи команды BEGIN TRANSACTION. Поэтому, дополнительный откат буфера по TableRevert() обычно не нужен (хотя и не помешает. Были глюки с буферами в подобных ситуациях)

Таким образом, событие Error(), скорее всего, вообще не отработает. Даже если в процессе сохранния будут ошибки.

Снова проверил, не совсем так, я вставил специально ошибочно вставку:
Код: plaintext
1.
INSERT INTO TABLE3 VALUE ('A','Text1')
INSERT INTO TABLE3 VALUE (2,'Text2')
на что система ошибки незаметила и запулила мне в Table3 пять записей а не 6, без первой...
...
Рейтинг: 0 / 0
Транзакции
    #33779281
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Владимир!

Там всё боле запущено - ошибка явно генерится строкой a = b * k - хотя для
наглядности стоило просто написать там ERROR "Тут явно вызовем ошибку".
Мне не нравятся схемы, когда ROLLBACK и END TRANSACTION разнесены в разные
методы - вообще если позволяет версия, то наверное стоит использовать в
таких случаях try ... catch ... finally ... endtry - чтобы гарантированно не
вывалится из метода (в тот-же Error event например или того хуже в
глобальный ON ERROR)

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Транзакции
    #33779472
Sergey Ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ValeriiНарод, я бы уверен что оборачиваю критические процессы обновления таблиц правильно, но вот нарвался на проблему, которая заставила взглянуть по-другому на эти вещи...
Если интересно, то можете посмотреть sp_message_delete я привожу данную процедуру два раза - первый раз с TRY..CATCH , второй для VFP 9.1 OLE DB Provider - без данной полезной возможности...

Good luck!
...
Рейтинг: 0 / 0
Транзакции
    #33779605
Valerii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey Ch ValeriiНарод, я бы уверен что оборачиваю критические процессы обновления таблиц правильно, но вот нарвался на проблему, которая заставила взглянуть по-другому на эти вещи...
Если интересно, то можете посмотреть sp_message_delete я привожу данную процедуру два раза - первый раз с TRY..CATCH , второй для VFP 9.1 OLE DB Provider - без данной полезной возможности...

Good luck!

http://sp_message_delete не работает... ошибка в линке....
Плз, елси можно, хочеться посмотреть...
...
Рейтинг: 0 / 0
Транзакции
    #33779729
Sergey Ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valerii http://sp_message_delete не работает... ошибка в линке....
Плз, елси можно, хочеться посмотреть...

Исправленная ссылка

Sorry, for any inconveniences...
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Транзакции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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