:: Visual Foxpro, Foxpro for DOS
Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
Всем привет.
Столкнулась со странностью. Отрабатывает процедура на стороне БД Оракл, делает определенные действия по условиям с одной из таблиц, апдейт, инсерт. Форсируется ее запуск с клиента VFP8. По окончании ее действия посылается Sqlcommit. Если потом с клиента послать к этой таблице над которой работала проца простой SELECT, то на клиента возвращаются актуальные обновленные данные, значит коммит отработал. Но если с клиента послать транзакцию инсерт в другую таблицу на основе селекта из обновленной только что таблицы (insert into таблица 2 селект таблица_обновленная), то этих последних обновлений "как будто не видно" идет инсерт старых данных, т.е. предыдущих до обновления. Если захожу PL\SQL Developerom, (но получается что ссеия другая) то вижу, что таблица обновлена и данные корректные.
Почему же при отправке с клиента в одной и той же сессии, простой селект возвращает обновленные данные, а транзакция инсерт на основе этого же селект делает вставку предыдущих до обновления данных?


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...
Ratings: 0 negative/0 positive
Re: Транзакции
PaulWist

Сообщений: 14621
Дата регистрации: 01.04.2004
Что возвращает Sqlcommit?


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
PaulWist
Что возвращает Sqlcommit?
Возвращает 1 Т.е. всё должно быть прекрасно, все изменения закомичены в базе...Я второй день бьюсь над этой странностью и понять не могу где собака зарыта.


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 1 раз(а). Последнее : Божья_коровка, 06.01.21 13:51
Ratings: 0 negative/0 positive
Re: Транзакции
PaulWist

Сообщений: 14621
Дата регистрации: 01.04.2004
Похоже на вложенные транзакции, посмотри аналог в Оракле, @@trancount - те на каком уровне вложенности транзакции находимся.

Может триггер срабатывает, без генерации ошибки.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 1 раз(а). Последнее : PaulWist, 06.01.21 14:13
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
PaulWist
Может триггер срабатывает, без генерации ошибки.
Триггер на таблице есть, формирует уникальный айдшник при вставке и при обновлении. Я ведь захожу девелопером и вижу, что данные то обновились, проца отработала корректно, ничто и нигде "не подвисло". Да и простой селект на клиента в той же сессии тоже возвращает обновлённые данные.

PaulWist
посмотри аналог в Оракле, @@trancount
А что это такое? Хотя бы в двух понятных словах, чтобы не перелопачивать всю информацию в хелпе.
вот почитала тут www.sql.ru Выпила вина, потому что нифига не поняла, и что делать? :al:


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 3 раз(а). Последнее : Божья_коровка, 06.01.21 16:26
Ratings: 0 negative/0 positive
Re: Транзакции
PaulWist

Сообщений: 14621
Дата регистрации: 01.04.2004
Ммм, без репо-кода трудно.

Ну давай дальше искать.

1. Уровень изоляции какой стоит (TIL)?

2. @@trancount - показывает уровень вложенности транзакции, те фактически количество команд Begin Tran.
Например у тебя такой код:

Begin tran
Begin tran
select @@trancount -- покажет 2
commit tran
select @@trancount -- покажет 1
commit tran
select @@trancount -- покажет 0

т.е. ты читаешь данные из незафиксированной транзакции (первый select), хотя формально выдана команда commit.

3. Какой режим закрытия транзакция стоит в фоксе, sqlgetprop(nConnection, 'Transaction')


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Транзакции
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
В оракле нет никаких вложенных транзакций - есть автономные, но это совсем другое дело. Есть savepoint-ы, но и это не "вложенные транзакции".
Клиентское управление транзакциями (sqlcommit) может некорректно пересекаться с серверным управлением транзакциями (если таковое прописано в ХП) - лучше так НЕ делать. Либо клиент управляет (а на сервере никаких коммитов), либо сервер управляет, но тогда клиент никаких sqlcommit не должен посылать (он то, конечно, может - но смысла в этом будет ровно 0, т.к. ничего фиксировать этот коммит не будет, равно как и sqlrollback ничего не откатит).

Описываемое поведение весьма странное - даже без коммита внутри одной транзакции будут видны все изменения сделанные в некоторой таблице (конечно же изменения сделанные в рамках этой транзакции). Создаётся впечатление, что на самом деле этот insert into ... select ... исполняется в отдельном клиентском процессе (т.е. для него сделано отдельное соединение), при том там включен режим транзакций serializable и сама транзакция стартовала ДО начла изменений таблицы-источника. Но тогда и обычный Select выполненный из этого контекста "не увидит" изменений.


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
Igor Korolyov
Описываемое поведение весьма странное - даже без коммита внутри одной транзакции будут видны все изменения сделанные в некоторой таблице (конечно же изменения сделанные в рамках этой транзакции). Создаётся впечатление, что на самом деле этот insert into ... select ... исполняется в отдельном клиентском процессе (т.е. для него сделано отдельное соединение), при том там включен режим транзакций serializable и сама транзакция стартовала ДО начла изменений таблицы-источника. Но тогда и обычный Select выполненный из этого контекста "не увидит" изменений.
Я сама понимаю, что столкнулась с очень странной ситуацией. Нет там никакого отдельного соединения не присутствует, всё выполняется в одной сессии, я эту транзакцию insert into ... select ... посылаю сразу же после того как отработала проца. Два дня ковырялась, так и не поняла в чем дело. Обошла эту странность как раз простым селектом. После проработки процы посылаю с клиента селект, тяну в курсор данные, загоняю в переменные, обрабатываю типы и посылаю инсерт на основе этих переменных. Это получается километр лишнего кода, ну и решение так себе. Ведь куда проще послать транзакцию в три строки и всё четко и понятно.


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 1 раз(а). Последнее : Божья_коровка, 07.01.21 17:07
Ratings: 0 negative/0 positive
Re: Транзакции
Владимир Максимов

Сообщений: 14100
Откуда: Москва
Дата регистрации: 02.09.2000
А можно хотя бы в виде псевдокода боле подробно описать, что происходит?

* Настраиваем ручной режим завершения транзакции (иначе смысла в SqlCommit нет)
= SQLSETPROP(m.ch, 'Transactions', 2)
* Со стороны VFP8 запускаем процедуру Oracle
=SQLExec(m.ch, 'Call MyProc')
* Явно завершаем транзакцию
isOk = SqlCommit(m.ch)
* Если делаем явную выборку, то получаем актуальные данные
=SQLExec(m.ch, 'select * from MyTab', 'curTest')
select curTest
BROWSE NOWAIT
* Если делаем вставку в другую таблицу напрямую
=SQLExec(m.ch, 'insert into MyTab2 select * from MyTab')
* То добавленные данные - это данные до завершения транзакции
=SQLExec(m.ch, 'select * from MyTab2', 'curTest2')
select curTest2
BROWSE NOWAIT

Вот это было сделано?

Те записи, которые просматриваешь в MyTab напрямую - это именно те записи, которые потом вставляешь в MyTab2? Там в команде INSERT нет какого-либо дополнительного WHERE или хитрых триггеров на самой таблице?
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
Начало всё как вы и написали -

* Настраиваем ручной режим завершения транзакции (иначе смысла в SqlCommit нет)
= SQLSETPROP(m.ch, 'Transactions', 2)
* Со стороны VFP8 запускаем процедуру Oracle
=SQLExec(m.ch, 'Call MyProc')
* Явно завершаем транзакцию
isOk = SqlCommit(m.ch)
После успешного завершения работы процы, т.е. после isOk = SqlCommit(m.ch) посылаю с клиента транзакцию -

=SQLExec(m.ch, 'insert into tabl2 (перечисление полей) select (перечисление полей) from MyTab where id = тут айдишник записи')
isOk = SqlCommit(m.ch)

И после этой транзакции заглядываю в tabl2 и вижу, что вставка произошла не последних обновленных данных после процедуры, а предыдущих. Открываю PL\SQL Developrom таблицу MyTab вижу, что данные на самом деле обновлены.

Далее чтобы понять, чтобы убедиться что данные обновились в той же сессии (все таки монитор это другая уже сессия) отрабатываю код -

* Настраиваем ручной режим завершения транзакции (иначе смысла в SqlCommit нет)
= SQLSETPROP(m.ch, 'Transactions', 2)
* Со стороны VFP8 запускаем процедуру Oracle
=SQLExec(m.ch, 'Call MyProc')
* Явно завершаем транзакцию
isOk = SqlCommit(m.ch)
* Если делаем явную выборку, то получаем актуальные данные
* ID в where один и тот же послается
=SQLExec(m.ch, 'select * from MyTab where id = тут айдишник записи', 'curTest')
select curTest
BROWSE NOWAIT
Получаю актуальные данные, т.е. они обновились. Но как только посылаю далее транзакцию, то вставка идет предыдущих данных -

* Настраиваем ручной режим завершения транзакции (иначе смысла в SqlCommit нет)
= SQLSETPROP(m.ch, 'Transactions', 2)
* Со стороны VFP8 запускаем процедуру Oracle
=SQLExec(m.ch, 'Call MyProc')
* Явно завершаем транзакцию
isOk = SqlCommit(m.ch)
*посылаю с клиента транзакцию -
=SQLExec(m.ch, 'insert into tabl2 (перечисление полей) select (перечисление полей) from MyTab where id = тут айдишник записи')
isOk = SqlCommit(m.ch)


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 6 раз(а). Последнее : Божья_коровка, 08.01.21 21:59
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
В итоге пришлось отказаться от транзакции -

=SQLExec(m.ch, 'insert into tabl2 (перечисление полей) select (перечисление полей) from MyTab where id = тут айдишник записи')
и делать селект
=SQLExec(m.ch, 'select (перечисление полей) from MyTab where id = тут айдишник записи', 'curTest')
обрабатывать типы данных, загонять их в переменные и делать инсерт на основе этих переменных

=SQLExec(m.ch, 'insert into tabl2 (перечисление полей) values (перечисление переменных)')


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 1 раз(а). Последнее : Божья_коровка, 08.01.21 21:58
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
По поводу хитрых триггеров, - их на таблице MyTab нет. Висит один триггер, который при апдейте записи формирует айдишник изменения. Ничего в нем хитрого нет, несколько строчек.

Т.е. я не смогла выяснить почему транзакция инсерт на основе селекта из таблицы, которая была обновлена процедурой вставляет данные предыдущие, а не только что обновленные, тогда как по факту они обновлены и зафиксированы, ведь простой селект на клиента тянет курсор с корректными последними обновлёнными данными.


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 1 раз(а). Последнее : Божья_коровка, 08.01.21 22:06
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
За эти два дня баловалась по всякому даже прописывала такое безобразие -

* Настраиваем ручной режим завершения транзакции (иначе смысла в SqlCommit нет)
= SQLSETPROP(m.ch, 'Transactions', 2)
* Со стороны VFP8 запускаем процедуру Oracle
=SQLExec(m.ch, 'Call MyProc')
* Явно завершаем транзакцию
isOk = SqlCommit(m.ch)
* Если делаем явную выборку, то получаем актуальные данные
* ID в where один и тот же послается
=SQLExec(m.ch, 'select * from MyTab where id = тут айдишник записи', 'curTest')
select curTest
IF curTest.pole1 = 'обновленное значение'
* если данные обновились то сделать транзакцию
=SQLExec(m.ch, 'insert into tabl2 (перечисление полей) select (перечисление полей) from MyTab where id = тут айдишник записи')
isOk = SqlCommit(m.ch)
ELSE
messagebox ('Всё плохо, ничего не обновилось, транзакцию не посылаю')
ENDIF
В общем, селект возвращает обновлённые данные, программа заходит в ветку IF отрабатывает транзакция, которая вставляет предыдущие данные, как будто для нее не существует обновленных данных.


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 1 раз(а). Последнее : Божья_коровка, 08.01.21 22:18
Ratings: 0 negative/0 positive
Re: Транзакции
PaulWist

Сообщений: 14621
Дата регистрации: 01.04.2004
Теоретически все правильно, попробуй после первого sqlcommit перевести соединение в автоматический режим и выполнить insert, возможно какие-то косяки с драйвером.

Ну и профайлером посмотреть надо какие команды север выполняет.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 1 раз(а). Последнее : PaulWist, 08.01.21 23:06
Ratings: 0 negative/0 positive
Re: Транзакции
leonid

Сообщений: 3204
Откуда: Рига
Дата регистрации: 03.02.2006
А я бы посоветовал вот это

* Явно завершаем транзакцию
isOk = SqlCommit(m.ch)

нафиг выбросить и посмотреть, что будет
Ratings: 0 negative/0 positive
Re: Транзакции
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Без вот этого
Божья_коровка
MyProc
вот этого
Божья_коровка
Висит один триггер, который при апдейте записи формирует айдишник изменения.
и вот этого
Божья_коровка
where id = тут айдишник записи
А так же понимания того что такое
Божья_коровка
данные предыдущие, а не только что обновленные
Нереально что либо понять.

Ну можно лишь посоветовать сделать тест - БЕЗ всего этого, без триггера, без условия в insert ... select, без ХП - чисто какой update или insert напрямую послать - и если и тогда будут "чудеса" - ну это значит системная проблема (остаётся лишь серверную трассировку включать и смотреть что происходит). Пока же есть шанс что дело таки в коде.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Транзакции
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
() а если делать операции с Ораклом без указания "начало/конец", т.е. без транзакций, то работает как надо?
Ratings: 0 negative/0 positive
Re: Транзакции
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Транзакции там будут по любому, просто в режиме
SQLSETPROP(m.ch, 'Transactions', 1) && Automatic
они будут неявно коммитится после каждого SQLEXEC.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Транзакции
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Акцент в вопросе был "с автоматическим управлением транзакциями (умолчательными транзакциями), или при полном их отключении (если это возможно) работает так, как надо?"
Ratings: 0 negative/0 positive
Re: Транзакции
Божья_коровка
Автор

Сообщений: 25731
Дата регистрации: 23.08.2001
of63
Акцент в вопросе был "с автоматическим управлением транзакциями (умолчательными транзакциями), или при полном их отключении (если это возможно) работает так, как надо?"
Я не поняла вопроса, что значит - "умолчательными транзакциями"? И что значит при полном их отключении? В двух словах объясни, что ты имеешь в виду...


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 24 (Гостей: 24)

© 2000-2024 Fox Club 
Яндекс.Метрика