Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Помогите разобраться / 25 сообщений из 29, страница 1 из 2
09.02.2003, 12:10
    #32103506
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Есть таблица 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 (по умолчанию).

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

похоже ты прав. попробуй в запросе использовать хинт - может поможет with nolock, подробнее в BOL'e
...
Рейтинг: 0 / 0
10.02.2003, 11:00
    #32103696
Alex Alexeev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
ilReadUncommitted - позволяет читать "грязные данные" других транзакций,
Т.е. этот уровень изоляции нужно выставлять в adoconnection2
...
Рейтинг: 0 / 0
10.02.2003, 11:07
    #32103700
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
2 Cat2
с одного клиента нельзя запустить две параллельных транзакции

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

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

2 hDrummer

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

Может имеет значение, что версия Personal Edition?
...
Рейтинг: 0 / 0
10.02.2003, 11:09
    #32103704
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
2 Alex Alexeev

А какой уровень нужно поставить в adoconnection1, чтобы другой зверь не мог открыть эту же транзакцию?
...
Рейтинг: 0 / 0
10.02.2003, 14:28
    #32103866
Alex Alexeev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
2 Cooper

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

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

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

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


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

а здесь READ UNCOMMITED (ilReadUncommitted), но никто не гарантирует, в таком случае, что они (другие пользователи) считывают актуальные данные !!!
...
Рейтинг: 0 / 0
10.02.2003, 14:55
    #32103909
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
2 Alex Alexeev

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

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

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


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

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

Вторая транзакция
select * from mytable with (nolock) where ...
...
Рейтинг: 0 / 0
10.02.2003, 17:34
    #32104095
ziktuw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Как только данные были фактически изменены, то до конца транзакции устанавливается эксклюзивная блокировка на эти измененные записи, и поэтому их нельзя прочитать ни из какой другой транзакции при её любом уровне.

Тут вам не здесь, понимаишь.
...
Рейтинг: 0 / 0
10.02.2003, 19:41
    #32104192
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Ну наконец-то я понял, что надо.

Ввести в строку с заголовком накладной поле - признак редактирования.
В одной транзакции считать данные по этой накладной на клиента и выставить в поле признак редактирования.
Сидеть, думать.
В единой транзакции удалить старые, ввести новые данные и снять флаг редактирования.

Каждый "редактор" накладных перед редактированием проверят, не стоит ли флаг. Если стоит - получает отлуп.
...
Рейтинг: 0 / 0
11.02.2003, 09:16
    #32104303
hDrummer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Как только данные были фактически изменены, то до конца транзакции устанавливается эксклюзивная блокировка на эти измененные записи, и поэтому их нельзя прочитать ни из какой другой транзакции при её любом уровне.

BOL врёт получается ;) ?

SET TRANSACTION ISOLATION LEVEL
Controls the default transaction locking behavior for all Microsoft® SQL Server™ SELECT statements issued by a connection.

Syntax
SET TRANSACTION ISOLATION LEVEL
{ READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE
}

Arguments
READ COMMITTED

Specifies that shared locks are held while the data is being read to avoid dirty reads, but the data can be changed before the end of the transaction, resulting in nonrepeatable reads or phantom data. This option is the SQL Server default.


READ UNCOMMITTED

Implements dirty read, or isolation level 0 locking, which means that no shared locks are issued and no exclusive locks are honored. When this option is set, it is possible to read uncommitted or dirty data; values in the data can be changed and rows can appear or disappear in the data set before the end of the transaction. This option has the same effect as setting NOLOCK on all tables in all SELECT statements in a transaction. This is the least restrictive of the four isolation levels.
...
Рейтинг: 0 / 0
11.02.2003, 09:34
    #32104322
Белов Владимир
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Естесственно не сожешь прочитать эту строку, так она блокирована сервером.
Сделать чтение с подсказкой nolock и не мудри с уровнем изоляции на клиенте.
...
Рейтинг: 0 / 0
11.02.2003, 09:58
    #32104340
Alex Alexeev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
В Query Analyzer
Окно 1
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
begin tran

select title from pubs.dbo.titles where title_id = 'BU1032'

update pubs.dbo.titles
  set title = 'bla-bla'
  where title_id = 'BU1032'

 --rollback tran
 


Окно 2
Код: plaintext
1.
2.
set transaction isolation level READ UNCOMMITTED 
select title from pubs.dbo.titles where title_id = 'BU1032'


Запускаем скрипт 1 смотрим значение title
Запускаем скрипт 2 смотрим значение title
Видим разные значения а ведь транзакция 1 не закрыта!!!
Откатываем транзакцию 1 (выделяем rollback tran и нажимаем F5)
Запускаем скрипт 2 смотрим значение title - старое значение !!!

т.е. BOL все-таки не врет
...
Рейтинг: 0 / 0
11.02.2003, 11:16
    #32104391
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
2 Dankov

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

Я далеко не спец, но подозреваю, что ты не прав (нутром чую).

2 Cat2

Такой подход мне сразу пришел в голову. Но я подумал, что так нехорошо делать. Но если ты советуюшь, это дает мне зеленый свет. Вот тока я думаю не получится так, что признак редактирования будет поставлен, а после редактирования не будет убран (ну там чего нить отвалилось например). И получится, что эта накладная будет вечно занята. А?

2 Белов Владимир
Естесственно не сожешь прочитать эту строку, так она блокирована сервером.

Почему? В книгах (по SQL SERVER) написано, то это можно сделать. Да и в BOL тоже написано. Это вроде как называется грязным чтением.

2 Alex Alexeev
А как быть, чтобы пока транзакция (которая редактирует запись) не закрыта, другая транзакция читает старое значение записи. Ведь мало ли чего. Вдруг юзер передумает и откатит транзакцию. А?

Всем спасибо.
...
Рейтинг: 0 / 0
11.02.2003, 11:54
    #32104425
Alex Alexeev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
А как быть, чтобы пока транзакция (которая редактирует запись) не закрыта, другая транзакция читает старое значение записи. Ведь мало ли чего. Вдруг юзер передумает и откатит транзакцию. А?

В первой транзации
select * from mytable with (updlock, rowlock) where <условие фильтра чтобы не блокировать другие записи>
и держишь транзакцию открытой, в результате то что в условии фильтра другим пользователям видно, но изменять данные они не могут

Затем, пользователь плющит чего надо в диалоговом окне,

Потом Update My table ... и быстренько подтвердить / откатить транзакцию.

во второй транзакции уровень изоляции READ COMMITED
...
Рейтинг: 0 / 0
11.02.2003, 12:25
    #32104447
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Спасибо.

Мне теперь информации на неделю хватит, чтобы переварить.
...
Рейтинг: 0 / 0
11.02.2003, 22:19
    #32104821
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Alex Alexeev
Проводим эксперимент

В одном окне QA запускаем
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Use NorthWind
exec sp_lock
go

begin transaction
select *
from Orders m with (updlock, rowlock) 
join [Order details] d with (updlock, rowlock) 
on m.OrderID=d.OrderID
where m.OrderID= 10248 

 --commit transaction
 


В другом окне QA запускаем
Код: plaintext
1.
2.
3.
4.
5.
6.
Use NorthWind
exec sp_lock
go
update Orders
set OrderDate=getDate()
where OrderID= 10248   

И тишина...
В результате имеем такую ситуацию. Юзер1 начал радактирование, хлопнулся в обморок и его увезла скорая. Или он просто отвлекся, забыл про редактирование, закрыл кабинет и уехал в командировку. Юзер2 пытается изменить документ и получает зависшую машину. Долго ищут админа, который бы разрулил ситуацию.
Наверное можно наворотить супер-пупер процедуру, которая будет проверять, не наложены ли на ряды блокировки, но это такой гимор... Сравните результаты выполнения процедуры sp_lock в одоих окнах и увидите, куда рыть придется.

Все таки блокировки предназначены для обеспечения целостности данных, а не для контроля за редактированием. И интерактивные действия во время транзакции плохо в любом случае.

==
Что делать, если флаг редактирования не снят?
При нормальном планировании транзакций это возможно только в случае аварийного отключения клиента. Лечится так - при входе в базу клиент снимает все поставленые им флаги. В качестве занчения флага лучше всего использовать userID клиента.
...
Рейтинг: 0 / 0
12.02.2003, 07:53
    #32104882
Alex Alexeev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Все таки блокировки предназначены для обеспечения целостности данных, а не для контроля за редактированием. И интерактивные действия во время транзакции плохо в любом случае.
Согласен и я об этом уже писал в этом топике.
Но вот надо человеку, и спрашивает он: "Как?"

Насчет эксперимента - Cooper спрашивал как во время выполнения транзакции разрешить другим пользователям просматривать данные, но не давать изменять их. Так что пример не совсем к месту, хотя и наглядно показывает чем чреваты интерактивные транзакции.
...
Рейтинг: 0 / 0
12.02.2003, 12:17
    #32105038
tygra
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Значит никак - так, как он хочет.\r
\r
Если конечно он хочет хрустальной вазой гвозди заколачивать - пусть заколачивает, нечего ему в этом помогать, а то сами виноваты останемся, когда вазу разобьет \r
\r
Еще раз цитата Cat2, очень правильная\r
Все таки блокировки предназначены для обеспечения целостности данных, а не для контроля за редактированием \r
\r
Этим все сказано.\r
Поэтому контроль за редактированием - руками.\r
\r
тут pkarklin привел пример хранимой процедуры, которая это обеспечивает.
...
Рейтинг: 0 / 0
12.02.2003, 13:44
    #32105120
Cooper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
2 tygra

Спасибо.
Как это я пропустил такой интересный топик.
...
Рейтинг: 0 / 0
12.02.2003, 22:33
    #32105430
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Alex Alexeev. Ваш пример прекрасно работает. Но Главный вопрос был - "помогите разобраться".
Как говорится, пользователю надо давать не то, что он просит, а то что ему надо.
...
Рейтинг: 0 / 0
13.02.2003, 07:26
    #32105476
Alex Alexeev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Да ладно-ладно, запинали уже


Все таки блокировки предназначены для обеспечения целостности данных, а не для контроля за редактированием. И интерактивные действия во время транзакции плохо в любом случае.

Совершенно согласен.
...
Рейтинг: 0 / 0
13.02.2003, 11:03
    #32105643
golsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
Такая ситуация разруливается просто:
Каждая запись снабжается подписью – двумя полями: кто и когда последний раз ее корректировал (последнее поле типа TimeStamp или DateTime - дата + время с десятитысячными долями сек.). Поля заполняются триггерами при Insert, Update.
Читаешь запись вместе с этими полями и отдаешь юзеру на растерзание. И только при записи в БД открываешь транзакцию и сперва проверяешь не изменились ли эти поля.
Если не изменились – пишешь.
Если изменились, вежливо обламываешь юзера - мол долго думал, холера, данные уже изменились. Закрываешь транзакцию. За одно некий мониторинг изменений важных данных.
...
Рейтинг: 0 / 0
13.02.2003, 22:26
    #32106308
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться
golsa, возможен и такой метод, но больно он нечеловеколюбивый. Представляете, юзер два часа парился, по факсу запросы посылал - детали уточнял, наконец нажал кнопку "сохранить", а ему "Пшел, вон. Запись изменена другим пользователем".
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Помогите разобраться / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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