Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / VFP+MS SQL транзакции / 5 сообщений из 5, страница 1 из 1
18.02.2006, 01:59
    #33553647
Valerii
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VFP+MS SQL транзакции
Кто подскажет правильную технику включения транзакции при записи в таблицы MS SQL
SQLEXEC(gnHandle, 'USE test')
SQLEXEC(gnHandle, 'BEGIN TRANSACTION')

SELECT Some_VFP_Cursor1
DO WHILE !EOF()
SQLEXEC(gnHandle, 'INSERT INTO Test VALUES ?x,?y,?z . ')
SKIP
ENDDO

SQLEXEC(gnHandle, 'USE test2')

SELECT Some_VFP_Cursor2

DO WHILE !EOF()
SQLEXEC(gnHandle, 'INSERT INTO Test2 VALUES ?x,?y,?z '
SKIP
ENDDO

SQLEXEC(gnHandle, 'END TRANSACTION')

Если где-то на серваке рухнуло в середине процесса, тогда ничего не запишет SQL в своих таблицах......

Такая техника правильная????
Всем спасибо...
...
Рейтинг: 0 / 0
18.02.2006, 04:46
    #33553690
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VFP+MS SQL транзакции
Hi Valerii!

SQLSETPROP(handle, "Transactions", 2), а потом SQLCOMMIT() и SQLROLLBACK()

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
18.02.2006, 09:32
    #33553726
Valerii
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VFP+MS SQL транзакции
Igor Korolyov
Hi Valerii!

SQLSETPROP(handle, "Transactions", 2), а потом SQLCOMMIT() и SQLROLLBACK()

Posted via ActualForum NNTP Server 1.3

Непонял, нужно только SQLSETPROP и все?
...
Рейтинг: 0 / 0
18.02.2006, 12:07
    #33553804
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VFP+MS SQL транзакции
Если необходимо обновить неколько таблиц на сервере в пределах одной транзакции, то я бы это обновление оформил в виде хранимой процедуры на сервере.
Если вы по какой то причине не хотите этого делать, то:
1. Установить на уровни сессии с сервером установку SET XACT_ABORT ON, которая будет заставлять откатывать сервером ВСЮ транзакцию при ошибки при исполнении любой команды.
2. Вызываете не команду SQLEXEC, а "обертку" (wrapper) для этого команды, которая будет при ошибки выполнения команды на сервере, явно откатывать транзакцию на сервере:
Код: plaintext
SQLEXEC(lhConnect, "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION")
С уважением, Алексей
...
Рейтинг: 0 / 0
18.02.2006, 12:36
    #33553817
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VFP+MS SQL транзакции
В FoxPro можно реализовать 2 механизма транзакции на SQL-сервере

1) Явно послать на сервер команды BEGIN TRANSACTION, END TRANSACTION, ROOLBACK. По сути, это то, что ты и написал:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
LOCAL llSuccess
llSuccess = .T.
IF m.llSuccess = .T.
	llSuccess = SQLEXEC(gnHandle, 'USE test')
ENDIF
IF m.llSuccess = .T.
	llSuccess = SQLEXEC(gnHandle, 'BEGIN TRANSACTION')
ENDIF

SELECT Some_VFP_Cursor1
GO TOP
SCAN WHILE m.llSuccess = .T.
	llSuccess = SQLEXEC(gnHandle, 'INSERT INTO Test VALUES (?x,?y,?z)')
ENDSCAN

IF m.llSuccess = .T.
	SQLEXEC(gnHandle, 'END TRANSACTION')
ELSE
	SQLEXEC(gnHandle, 'IF @@TRANCOUNT>0 ROLLBACK TRANSACTION')
	LOCAL laError( 1 )
	=AERROR(laError)
	* Разбираем массив laError для уточнения причины ошибки
ENDIF

Это был механизм ЯВНОГО начала транзакции

2) Можно указать для соединения специальную настройку

SQLSETPROP(handle, "Transactions", 2)

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

Т.е. при данной настройке, транзакция, неявно открытая любой командой на модификацию, останется "висеть", пока не будет подана на сервер специальная команда SQLCommit() или SQLRollback()

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
LOCAL llSuccess
llSuccess = .T.
SQLSETPROP(gnHandle, "Transactions",  2 )
IF m.llSuccess = .T.
	llSuccess = SQLEXEC(gnHandle, 'USE test')
ENDIF

SELECT Some_VFP_Cursor1
GO TOP
SCAN WHILE m.llSuccess = .T.
	llSuccess = SQLEXEC(gnHandle, 'INSERT INTO Test VALUES (?x,?y,?z)')
ENDSCAN

IF m.llSuccess = .T.
	llSuccess = SQLCOMMIT(gnHandle)
ENDIF
IF m.llSuccess = .F.
	LOCAL laError( 1 )
	=AERROR(laError)
	* Разбираем массив laError для уточнения причины ошибки
	* И, на всякий случай
	= SQLROLLBACK(gnHandle)
ENDIF

Кстати, я как-то не проверял, разве в MS SQL транзакция может быть распространена не НЕСКОЛЬКО баз данных? Мне всегда казалось, что транзакция - это функция одной базы данных, а не собственно SQL-сервера. Или я тут не прав?
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / VFP+MS SQL транзакции / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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