J'ai écrit un programme linq-to-sql qui effectue essentiellement une tâche ETL, et j'ai remarqué de nombreux endroits où la parallélisation améliorera ses performances. Cependant, je suis préoccupé par la prévention des violations de contraintes d'unicité lorsque deux threads exécutent la tâche suivante (code Psuedo).Quel niveau d'isolation dois-je utiliser pour la transaction suivante insérer-si-non-présent?
Record CreateRecord(string recordText)
{
using (MyDataContext database = GetDatabase())
{
Record existingRecord = database.MyTable.FirstOrDefault(record.KeyPredicate());
if(existingRecord == null)
{
existingRecord = CreateRecord(recordText);
database.MyTable.InsertOnSubmit(existingRecord);
}
database.SubmitChanges();
return existingRecord;
}
}
En général, ce code exécute une instruction SELECT
pour tester pour l'enregistrement existance, suivi d'une déclaration INSERT
si l'enregistrement n'existe pas. Il est encapsulé par une transaction implicite.
Lorsque deux threads exécutent ce code pour la même instance de recordText
, je souhaite les empêcher de déterminer simultanément que l'enregistrement n'existe pas, essayant ainsi de créer le même enregistrement. Un niveau d'isolement et une transaction explicite fonctionneront bien, sauf que je ne suis pas certain quel niveau d'isolation je devrais utiliser - Serializable
devrait fonctionner, mais semble trop strict. Y a-t-il un meilleur choix?