Méthode C # pour verrouiller la table SQL Server

J'ai un programme C# qui doit effectuer un groupe de mises à jour en masse (20k) dans une table SQL Server. Depuis que les autres utilisateurs peuvent mettre à jour ces enregistrements un à un via un site intranet, nous avons besoin de construire le programme C# avec la fonctionnalité de verrouillage de la table vers le bas. Une fois que la table est verrouillée pour empêcher un autre utilisateur d'y apporter des modifications/recherches on aura alors besoin de préformation de la demande de mises à jour/inserts.

Puisque nous sommes le traitement de nombreux dossiers, nous ne pouvons pas utiliser TransactionScope (semblait le moyen le plus facile au premier abord) due au fait que notre transaction vents est gérée par le Service MSDTC. Nous avons besoin d'utiliser une autre méthode.

Fondée sur ce que j'ai lu sur l'internet à l'aide d'un SqlTransaction objet semblait être la meilleure méthode, mais je ne peux pas obtenir le tableau de verrouillage. Lorsque le programme s'exécute et j'ai pas le code ci-dessous, je suis encore capable de faire des mises à jour et de la recherche via le site intranet.

Ma question est double. Suis-je à l'aide de la SqlTransaction correctement? Si oui (ou même si) il y a une meilleure méthode pour l'obtention d'un verrou de table qui permet au programme en cours d'exécution de la recherche et de la préformation des mises à jour?

Je voudrais pour la table pour être verrouillé alors que le programme exécute le code ci-dessous.

C#

SqlConnection dbConnection = new SqlConnection(dbConn);
dbConnection.Open();
using (SqlTransaction transaction = dbConnection.BeginTransaction(IsolationLevel.Serializable))
{
//Instantiate validation object with zip and channel values
_allRecords = GetRecords();
validation = new Validation();
validation.SetLists(_allRecords);
while (_reader.Read())
{
try
{
record = new ZipCodeTerritory();
_errorMsg = string.Empty;
//Convert row to ZipCodeTerritory type
record.ChannelCode = _reader[0].ToString();
record.DrmTerrDesc = _reader[1].ToString();
record.IndDistrnId = _reader[2].ToString();
record.StateCode = _reader[3].ToString().Trim();
record.ZipCode = _reader[4].ToString().Trim();
record.LastUpdateId = _reader[7].ToString();
record.ErrorCodes = _reader[8].ToString();
record.Status = _reader[9].ToString();
record.LastUpdateDate = DateTime.Now;
//Handle DateTime types separetly
DateTime value = new DateTime();
if (DateTime.TryParse(_reader[5].ToString(), out value))
{
record.EndDate = Convert.ToDateTime(_reader[5].ToString());
}
else
{
_errorMsg += "Invalid End Date; ";
}
if (DateTime.TryParse(_reader[6].ToString(), out value))
{
record.EffectiveDate = Convert.ToDateTime(_reader[6].ToString());
}
else
{
_errorMsg += "Invalid Effective Date; ";
}
//Do not process if we're missing LastUpdateId
if (string.IsNullOrEmpty(record.LastUpdateId))
{
_errorMsg += "Missing last update Id; ";
}
//Make sure primary key is valid
if (_reader[10] != DBNull.Value)
{
int id = 0;
if (int.TryParse(_reader[10].ToString(), out id))
{
record.Id = id;
}
else
{
_errorMsg += "Invalid Id; ";
}
}
//Validate business rules if data is properly formatted
if (string.IsNullOrWhiteSpace(_errorMsg))
{
_errorMsg = validation.ValidateZipCode(record);
}
//Skip record if any errors found
if (!string.IsNullOrWhiteSpace(_errorMsg))
{
_issues++;
//Convert to ZipCodeError type in case we have data/formatting errors
_errors.Add(new ZipCodeError(_reader), _errorMsg);
continue;
}
else if (flag)
{
//Separate updates to appropriate list
SendToUpdates(record);
}
}
catch (Exception ex)
{
_errors.Add(new ZipCodeError(_reader), "Job crashed reading this record, please review all columns.");
_issues++;
}
}//End while
//Updates occur in one of three methods below. If I step through the code,
//and stop the program here, before I enter any of the methods, and then 
//make updates to the same records via our intranet site the changes
//made on the site go through. No table locking has occured at this point. 
if (flag)
{
if (_insertList.Count > 0)
{
Updates.Insert(_insertList, _errors);
}
if (_updateList.Count > 0)
{
_updates = Updates.Update(_updateList, _errors);
_issues += _updateList.Count - _updates;
}
if (_autotermList.Count > 0)
{
//_autotermed = Updates.Update(_autotermList, _errors);
_autotermed = Updates.UpdateWithReporting(_autotermList, _errors);
_issues += _autotermList.Count - _autotermed;
}
} 
transaction.Commit();
}

source d'informationauteur NealR