Помогите разобраться

Cooper
Дата: 09.02.2003 12:10:13
Есть таблица Tab1 (на SQL Server 2000).
В делфях делаю так:

Активизирую соединение adoconnection1 и в нем указываю уровень изоляции ilReadUncommitted.
Открываю транзакцию - adoconnection1.begintrans.
Затем хранимой процедурой через это соединение читаю строку из таблицы Tab1, и редактирую эту запись. Транзакцию не закрываю.

Затем активизирую другое соединение adoconnection2.
Через хранимую процедуру хочу прочитать таблицу Tab1. Но прога вешается. То есть SQL Server не дает читать данные, которые модифицированы в другой транзакции (adoconnection1.begintrans).

P.S. В SLQ Server по умолчанию стоит уровень изоляции - Read Commited. Вот я и подозреваю, то что я указываю в соединении adoconnection1 уровень изоляции ilReadUncommitted никак не влияет на сервер. То есть уровень изоляции остается Read Commited (по умолчанию).

Помогите разобраться, что я делаю не так.
Cat2
Дата: 09.02.2003 22:33:00
Что-то про это обсуждалось на форуме MS SQL. Не помню, чем кончилось, но вроде тем, что с одного клиента нельзя запустить две параллельных транзакции.
hDrummer
Дата: 10.02.2003 09:07:41
P.S. В SLQ Server по умолчанию стоит уровень изоляции - Read Commited. Вот я и подозреваю, то что я указываю в соединении adoconnection1 уровень изоляции ilReadUncommitted никак не влияет на сервер. То есть уровень изоляции остается Read Commited (по умолчанию).

похоже ты прав. попробуй в запросе использовать хинт - может поможет with nolock, подробнее в BOL'e
Alex Alexeev
Дата: 10.02.2003 11:00:22
ilReadUncommitted - позволяет читать "грязные данные" других транзакций,
Т.е. этот уровень изоляции нужно выставлять в adoconnection2
Cooper
Дата: 10.02.2003 11:07:04
2 Cat2
с одного клиента нельзя запустить две параллельных транзакции

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

Например, есть таблица накладных. Она выводится в DBGrid через ХП. Затем один из юзеров хочет отредактировать какую-нить накладную. Он открывает через новое соединение транзакцию и читает в ней нужную запись. И нужно, чтобы другие юзеры уже не могли запустить эту транзакцию. Но могли просто читать данные (т.е. видеть журнал накладных).

2 hDrummer

Хинты тоже пробовал, но опять же SQL Server никак не реагирует на это.

Может имеет значение, что версия Personal Edition?
Cooper
Дата: 10.02.2003 11:09:54
2 Alex Alexeev

А какой уровень нужно поставить в adoconnection1, чтобы другой зверь не мог открыть эту же транзакцию?
Alex Alexeev
Дата: 10.02.2003 14:28:02
2Cooper

Например, есть таблица накладных. Она выводится в DBGrid через ХП. Затем один из юзеров хочет отредактировать какую-нить накладную. Он открывает через новое соединение транзакцию и читает в ней нужную запись.

1. А зачем через новое соединение-то ???!!!
2. Вообще-то не рекомендуется использовать "интерактивные" тразакции,
т.е. открывать транзакцию и ждать пока пользователь введет данные.
Но, конечно смотреть нужно по ситуации.

И нужно, чтобы другие юзеры уже не могли запустить эту транзакцию.

Эту транзакцию другие пользователи уже не запустят :)
Если ты имеешь ввиду запретить другим пользователем изменение данных после их считывания то нужно установить в первой транзакции уровень изоляции REPEATEBLE READ (ilRepeatableRead)


Но могли просто читать данные (т.е. видеть журнал накладных).

а здесь READ UNCOMMITED (ilReadUncommitted), но никто не гарантирует, в таком случае, что они (другие пользователи) считывают актуальные данные !!!
Cooper
Дата: 10.02.2003 14:55:19
2 Alex Alexeev

А зачем через новое соединение-то ???!!!

И правда. Мой касяк. Наверное можно в одном соединении.

Вообще-то не рекомендуется использовать "интерактивные" тразакции,
т.е. открывать транзакцию и ждать пока пользователь введет данные.
Но, конечно смотреть нужно по ситуации.


Вот у меня как раз такая ситуация. То есть юзер открыл форму (прочитал накладную) и может сидеть и не редактировать (так сказать думать) некоторое время. И нужно гарантировать, что за это время никто не сможет изменить эту запись (накладную).

Спасибо. Буду пробовать. Вот вчера целый день пытался сделать, но не получилось. Такое впечатление, что Сервер игнорирует установки уровня изоляции от клиента.
Alex Alexeev
Дата: 10.02.2003 15:31:30
Ну и ставь уровень изоляции на сервере
или используй хинты в запросах как тебе hDummer
и посоветовал
Ну типа первая транзакция
На клиенте: ADOConnection1.BeginTrans
на SQL-сервере select * from mytable with (updlock) where <и тут условие фильтра чтобы не блокировать остальные строки>

Вторая транзакция
select * from mytable with (nolock) where ...
ziktuw
Дата: 10.02.2003 17:34:00
Как только данные были фактически изменены, то до конца транзакции устанавливается эксклюзивная блокировка на эти измененные записи, и поэтому их нельзя прочитать ни из какой другой транзакции при её любом уровне.

Тут вам не здесь, понимаишь.