Транзакции SQL Server --- C # - PullRequest
       20

Транзакции SQL Server --- C #

0 голосов
/ 03 декабря 2009

Мне нужна помощь. Позвольте мне сначала объяснить сценарий с небольшой выборкой.

Предположим, у меня есть таблица Students со столбцами:

Id int(PK)  
Name varchar(200)  
Marks1 int  
Marks2 int  
Marks3 int  
TotalMarks int  
IsTotalCalculated bit  
InProcess bit

В этой таблице огромное количество записей.

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

Сейчас, заходя в консольное приложение C #, я вызываю хранимые процедуры:

SP1 => Я выбираю две верхние записи за раз, у которых InProcess = 0 и IsTotalCalculated = 0, устанавливает его InProcess = 1 и выполняю обработку. (Имеет ВЫБОР и ОБНОВЛЕНИЕ)

SP2 => Наконец, снова обновите эти две строки, что обновляет его IsTotalCalculated = 1 и InProcess = 0 (ОБНОВЛЕНИЕ)

Озабоченность: Меня беспокоит, как только я выберу 2 строки для обработки, тогда любой другой экземпляр Консольного приложения не должен выбирать эти 2 строки для обработки. Что мне делать?
Примечание. Я поместил код C # моих двух SP в TransactionBlock.

Спасибо,

Джастин Самуэль

Ответы [ 3 ]

1 голос
/ 03 декабря 2009

Разве вы не можете просто проверить в SP1, если InProcess = 1, а затем, если это правда, игнорировать остальные, пока InProcess не станет 0?

Хитрость заключается в том, чтобы блокировать любые чтения при обновлении InProcess до 1. Это можно сделать с помощью SET TRANSACTION ISOLATION LEVEL READ COMMITTED, который указывает, что операторы (в вашем SP) не могут читать данные, которые были изменены, но не зафиксированы другими транзакциями .

Надеюсь, это поможет.

1 голос
/ 03 декабря 2009

С какой стати вы хотите сделать это в C # ?? Это идеально для T-SQL!

 UPDATE 
     dbo.Students
 SET 
     TotalMarks = (some formula),
     IsTotalCalculated = 1
 WHERE 
     IsTotalCalulated = 0

Один оператор T-SQL, и все готово, не беспокойтесь о объемах транзакций и перетасовывании данных назад и вперед .......

ОК, так что если вы должны придерживаться своего текущего подхода - вот что вы могли бы сделать:

Озабоченность: мое беспокойство, как только я выберите 2 строки для обработки, затем любой другой экземпляр консольного приложения должен не выбирайте эти 2 строки для обработка. Что я должен делать?

Как насчет "скрытия" таблицы Students, например не разрешать кому-либо доступ к нему, а вместо этого использовать представление поверх него, которое только когда-либо показывает строки, которые имеют InProcess = 0?

CREATE VIEW dbo.StudentsView
AS
    SELECT (list of fields)
    FROM dbo.Students
    WHERE InProcess = 0

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

0 голосов
/ 03 декабря 2009

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

...