Проблема с транзакциями

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Проблема с транзакциями

Сообщение funtik_sql » 18.01.2007 (Чт) 11:10

Всем привет.
Проблема такая:
Есть программа в которой используется SQLServer2000.
После нажатия на одну из кнопок, я запускаю транзакцию.
Код: Выделить всё
cn.BeginTrans

После попытки выполнить SELECT возникает ошибка:

"Не удается создать новое подключение в режиме ручного или распределенного выполнения транзакции"

В чем может быть причина ошибки?

shady
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 09.11.2005 (Ср) 11:03

Сообщение shady » 18.01.2007 (Чт) 12:47

После попытки выполнить SELECT возникает ошибка

А какой селект? SELECT INTO?

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 18.01.2007 (Чт) 13:52

shady писал(а):
После попытки выполнить SELECT возникает ошибка

А какой селект? SELECT INTO?


Обычный запрос на чтение.
Код: Выделить всё
select * from table

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 18.01.2007 (Чт) 14:38

Может быть новая транзакция открывается на фоне уже запущенной?
OLEDB не допускает вложенных транзакций, вроде бы.
Lasciate ogni speranza, voi ch'entrate.

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 18.01.2007 (Чт) 14:45

alibek писал(а):Может быть новая транзакция открывается на фоне уже запущенной?
OLEDB не допускает вложенных транзакций, вроде бы.


А как узнать запущена еще одна транзакция или нет?

S397
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 02.12.2005 (Пт) 13:31

Сообщение S397 » 18.01.2007 (Чт) 15:10

Не удается создать новое подключение

Видимо перед выполнением Select создается новое соединение

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 18.01.2007 (Чт) 15:12

S397 писал(а):
Не удается создать новое подключение

Видимо перед выполнением Select создается новое соединение


Если только неявно, потому что сам я никаких подключений не создаю.
ПОчему тогда ADO пытается создать подключение?

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 18.01.2007 (Чт) 15:14

а зачем селект в транзакции выполнять?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 18.01.2007 (Чт) 15:14

alibek писал(а):Может быть новая транзакция открывается на фоне уже запущенной?
Нет, в этом случае описание ошибки так и гласило бы - типа уже есть транзакция.
Konst_One писал(а):а зачем селект в транзакции выполнять?
Вполне справедливый вопрос... Если select долгий, да еще из нескольких таблиц, то на время запроса все они будут заблокированы транзакцией.

funtik_sql, с какими параметрами открываешь соединение и рекордсет?
Лучший способ понять что-то самому — объяснить это другому.

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 18.01.2007 (Чт) 15:27

Antonariy писал(а):
alibek писал(а):Может быть новая транзакция открывается на фоне уже запущенной?
Нет, в этом случае описание ошибки так и гласило бы - типа уже есть транзакция.
Konst_One писал(а):а зачем селект в транзакции выполнять?
Вполне справедливый вопрос... Если select долгий, да еще из нескольких таблиц, то на время запроса все они будут заблокированы транзакцией.

funtik_sql, с какими параметрами открываешь соединение и рекордсет?


Код: Выделить всё
cn.BeginTrans
Set adoRs = New ADODB.Recordset
With adoRs
    .LockType = adLockOptimistic
    .CursorType = adOpenDynamic
    .CursorLocation = adUseClient
    buf = "SELECT * FROM Users WHERE name='Ivan'"
    .Open buf, cn
    If .EOF = True Then      ' если запись не существует
        If Len(Value) <= .Fields(1).DefinedSize Then 'если длина в норме
            .AddNew
            CreateRecord = NewID(MyConn, TabName, .Fields(0).name)
            If CreateRecord Then
                .Fields(0).Value = CreateRecord
                .Fields(1).Value = Value
                rsWriteServInfo adoRs, 1, 0
               .Update
            End If
         End If
    End If
End With

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 18.01.2007 (Чт) 15:33

Селект не долгий.Ради экперимента выбирал одну строку из простой таблицы - та же ошибка.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 18.01.2007 (Чт) 16:06

Код: Выделить всё
cn.BeginTrans
Set adoRs = New ADODB.Recordset
With adoRs
    SET .ActiveConnection=cn
    .LockType = adLockOptimistic
    .CursorType = adOpenDynamic
    .CursorLocation = adUseClient
    buf = "SELECT * FROM Users WHERE name='Ivan'"
    .Open buf
    If .EOF = True Then      ' если запись не существует
        If Len(Value) <= .Fields(1).DefinedSize Then 'если длина в норме
            .AddNew
            CreateRecord = NewID(MyConn, TabName, .Fields(0).name)
            If CreateRecord Then
                .Fields(0).Value = CreateRecord
                .Fields(1).Value = Value
                rsWriteServInfo adoRs, 1, 0
               .Update
            End If
         End If
    End If
End With


и все-таки я не понял зачем селект внутри транзакции :shock:

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 18.01.2007 (Чт) 16:13

Для проверки существования записей в БД.

shady
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 09.11.2005 (Ср) 11:03

Сообщение shady » 18.01.2007 (Чт) 16:41

Для проверки существования записей в БД.

Можно сделать
Код: Выделить всё
SELECT count(*) WHERE ...
хотя что будет работать быстрее я незнаю.
И я бы вот так сделал
Код: Выделить всё
Set adoRs = New ADODB.Recordset
With adoRs
    SET .ActiveConnection=cn
    .LockType = adLockOptimistic
    .CursorType = adOpenDynamic
    .CursorLocation = adUseClient
    buf = "SELECT * FROM Users WHERE name='Ivan'"
    .Open buf
    If .EOF = True Then      ' если запись не существует
        cn.BeginTrans
If Len(Value) <= .Fields(1).DefinedSize Then 'если длина в норме
            .AddNew
            CreateRecord = NewID(MyConn, TabName, .Fields(0).name)
            If CreateRecord Then
                .Fields(0).Value = CreateRecord
                .Fields(1).Value = Value
                rsWriteServInfo adoRs, 1, 0
               .Update
cn.CommitTrans
            End If
         End If
    End If
End With

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 18.01.2007 (Чт) 17:30

Самое главное - а нафига тут вообще транзакция?
Применительно к данному коду.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 18.01.2007 (Чт) 18:03

я тоже пока не понял

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Re: Проблема с транзакциями

Сообщение Ennor » 18.01.2007 (Чт) 18:04

"Не удается создать новое подключение в режиме ручного или распределенного выполнения транзакции"

Прямо вот так и пишет, по-русски? Да, на каком именно месте возникает ошибка - на вызове метода Recordset.Open() или еще где?..

И еще, покажи код инициализации объекта ADODB.Connection.

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Re: Проблема с транзакциями

Сообщение funtik_sql » 19.01.2007 (Пт) 11:00

Andrey Fedorov писал(а):Самое главное - а нафига тут вообще транзакция?
Применительно к данному коду.


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

Ennor писал(а):
"Не удается создать новое подключение в режиме ручного или распределенного выполнения транзакции"

Прямо вот так и пишет, по-русски? Да, на каком именно месте возникает ошибка - на вызове метода Recordset.Open() или еще где?..


Да, ошибка по-русски.Возникает именно Recordset.Open().

Ennor писал(а):И еще, покажи код инициализации объекта ADODB.Connection.


Код: Выделить всё

Set cn = New ADODB.Connection
buf = "File Name=" + DirPath + "file.udl"
cn.ConnectionString = buf
cn.Open


file udl:
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBSQL;Data Source=localcomp

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 19.01.2007 (Пт) 11:16

С динамическим курсором транзакции вроде не работают... Или с оптимистической блокировкой. Здесь собака порылась.
Лучший способ понять что-то самому — объяснить это другому.

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 19.01.2007 (Пт) 11:41

Да стоит добавить что в Access все пректасно работало.
Ошибки начали возникать именно при переходе на SQL2000

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 19.01.2007 (Пт) 11:44

Закомментируй запрос и выполни SELECT @@TRANCOUNT. Все больше подозреваю вложенную транзакцию.
Lasciate ogni speranza, voi ch'entrate.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 19.01.2007 (Пт) 11:46

ну так нестэд транзакции не поддерживаются провайдером доступа к данным Microsoft OLE DB Provider for SQL Server

и вообще, все что ты там понаписал надо выносить на сервер SQL в виде хранимых процедур, а их уже запускать из твоего кода. Транзакции уже , если они конечно требуются, можно в хранимках юзать.

PS
пока сочинял, Алибек уже мысль уловил :wink:

funtik_sql
Начинающий
Начинающий
 
Сообщения: 19
Зарегистрирован: 26.12.2006 (Вт) 11:52

Сообщение funtik_sql » 19.01.2007 (Пт) 12:25

alibek писал(а):Закомментируй запрос и выполни SELECT @@TRANCOUNT. Все больше подозреваю вложенную транзакцию.


А где надо выполнить SELECT @@TRANCOUNT?
Если выполнять на сервере в момент когда программа выполняет BeginTrans то та 0(как до BeginTrans так и после BeginTrans)
С клиента не удается выполнить из-за той самой ошибки.

По поводу хранимок у меня имя таблицы и параметры не известны так что приходится на клиенте создавать запрос.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 19.01.2007 (Пт) 12:57

динамический SQL для этого существует на сервере и команды sp_executesql, exec, sp_execute


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 55

    TopList