2015-07-09 3 views
0

Предположим, что у меня есть таблица из 100 строк, я просто хочу выбрать 10 лучших строк таблицы, но моя ситуация в том, что я хочу выбрать только те строки, которые ранее не обрабатывались. Для этого я добавил столбец «Флаг», чтобы я обновлял всякий раз, когда обрабатываю строки.Не повторяется Чтение из таблицы базы данных в SQL Server

Но здесь проблема возникает, когда параллельный запрос поступает на верхние 10 строк. Оба могут получать одинаковые строки и пытаться обновить одни и те же строки (чего я не хочу делать).

Здесь я не могу использовать Begin Transaction, потому что он заблокирует таблицу, а параллельный запрос не будет обработан.

Требования: Мое фактическое требование Когда я выбор топ 10 строк используя условие флага и обновление затем, а затем, если другой запрос для же он будет также выбрать другие верхние 10 строк, не орудуя Запроса 1.

Example : My table contains 100 rows. 
{ 
Select top 10 * from table_name where flag=0 

update table_name set top 10 flag = 1 
} 
(Will select top 10 out of 100 rows n update) 


if at the same time during above request, another request come, 
{ 
Select top 10 * from table_name where flag=0 (Should skip previous request rows) 

update table_name set top 10 flag = 1 
} 
Need: (Will select top 10 out of rest 90 rows n update) 

I Need замок на вершине 10 строк первого запроса, но замок хотел пропустить строки первого запроса, даже при одновременном отборного заявления обоих запросов

Пожалуйста, помогите мне решить эту проблему.

+0

Thanx Ameya для того, чтобы перефразировать вопрос. Не могли бы вы мне помочь? –

+0

1. Одновременная фантазия нашего воображения. 2.Что вам действительно нужно? нормально ли, если первый запрос блокирует всю таблицу в течение очень короткого периода времени (миллисекунды или менее), и что следующий запрос будет ждать завершения этой части, прежде чем выбрать собственную группу из 10 строк? – Amit

+0

@Amit: Я не хочу блокировать всю таблицу, как я упоминал в вопросе. Таким образом, он будет действовать как один за другим. Мне просто нужен оптимизированный способ, предполагающий 1 миллион общих строк в таблице. Таким образом, по одной моде может потребоваться много времени. Morever, Мне нужны не повторяемые чтения. Есть ли способ, чтобы он выбирал только те строки, которые ранее не читались. Извините за такое длинное описание. –

ответ

1

Вы можете использовать предложение OUTPUT для выполнения как выбора, так и обновления флага в одном из утверждений, например.

UPDATE TOP 10 table 
SET flag = 1 
WHERE flag = 0 
OUTPUT inserted.* 
+0

также должен добавить подсказку readpast – dean

+0

@dean: Я узнал о подсказке readpast. Но предотвращает ли выбор строк, которые становятся модифицированными транзакцией 1, вместо этого мне нужно, чтобы чужие могли выбрать еще 10 строк вместо этих 10 строк, которые одновременно обновляются транзакцией 1 –

+0

, если строка заблокирована обновлением в одном транзакция, обновление второй транзакции пропустит эту строку без ожидания - я предполагаю, что это было ваше намерение, не так ли? – dean

0

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

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

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

Что касается вашего неповторяющегося гласит:

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

Transaction with ISOLATION LEVEL REPEATABLE READ 
{ 
    select top 10 rows 
    update select-flag 
    return the 10 rows 
} 

normal query 
{ 
    take the returned 10 rows and do something 
    change updated-flag 
} 

Trigger after update if updated-flag changed 
{ 
    copy updated to read-history-table 
    delete updated-rows 
} 

ISOLATION LEVELS on MSDN

REPEATABLE READ «Указывает, что заявления не может читать данные, которые были изменены, но еще не совершенные другими транзакциями и что никакие другие транзакции не могут изменять данные, которые считаны по текущей сделке до завершения текущей транзакции. "

+0

Вот как, во время выбора оба запроса получат одни и те же данные, но в то время один запрос обновляет данные, но во время блокировки второй запрос будет ждать завершения транзакции, после чего он снова обновит те же строки, что и не модификация. В конечном итоге оба запроса получают одинаковые строки, которые я не хочу. Спасибо за ваше хорошее объяснение, но оно не соответствовало моему требованию. –

+0

см. Мое последнее изменение, чтобы уточнить, что я имел в виду – KarmaEDV

+0

@VikrantMishra. Ваш комментарий неправильный, и этот ответ я предложил в своем комментарии. Пожалуйста, постарайтесь уделять больше внимания, чтобы понять это, поскольку оно, вероятно, сделает то, что вам нужно. – Amit

Смежные вопросы