2009-06-02 14 views
5

Mam kawałek kodu, który wygląda mniej więcej tak (ClearImportTable i InsertPage są procedury przechowywane):Jak używać transakcji w LINQ do SQL przy użyciu procedur przechowywanych?

datacontext.ClearImportTable() //Essentially a DELETE FROM table 
for (int i = 1; i < MAX_PAGES; ++i){ 
    datacontext.InsertPage(i); //Inserts data into the table 
} 

Jest to nieco uproszczona wersja mojego kodu, ale chodzi o to, że czyści stół przed włożeniem dokumentacja. Jedynym problemem jest to, że jeśli wystąpi błąd po ClearImportTable, wszystkie dane z tabeli zostaną wyczyszczone. Czy istnieje sposób na zawarcie tego w transakcji, tak aby w przypadku jakichkolwiek błędów wszystko zostanie przywrócone tak, jak było?

Odpowiedz

9

można zrobić zakres transakcji:

using (var transaction = new TransactionScope()) 
{ 
    // do stuff here... 
    transaction.Complete(); 
} 

Jeśli wystąpi wyjątek lub przy użyciu bloku pozostaje bez uderzania transaction.Complete(), a następnie wszystko wykonywane wewnątrz przy użyciu bloku jest wycofana.

Należy odwołać się do zestawu System.transactions.

+0

Wymaga to użycia MSDTC, co nie zawsze jest dobrym pomysłem. –

+0

Wierzę, że MSDTC jest potrzebny tylko wtedy, gdy utworzysz więcej niż jeden wiersz danych w ramach usługi transqation i uruchomisz kwerendy przeciwko nim. Jeśli utworzysz tylko jeden obiekt datacontext w zakresie transakcji, nie będzie to wymagane. –

+1

MSDTC jest wymagany tylko w przypadku wielu menedżerów zasobów. Tak długo, jak obejmuje tylko jeden DataContext i połączyć się z jednym wystąpienie SQL Server, należy użyć transakcji lekkich. – jrista

0

Ustaw właściwość Transaction na DataContext?

9

Jak wspomniano wyżej w temacie "Sailing Judo", użyłem bloków TransactionScope z wielkim sukcesem, gdy potrzebuję wywołać przechowywane proc. Jest jednak jedna "gotcha", w którą wpadłem, gdzie wyjątek zostaje rzucony, mówiąc, że "transakcja jest wątpliwa". Aby obejść ten problem, musiałem wywołać niedocenianą metodę na proc, aby natychmiast ocenić wynik. Więc zamiast

using (var transaction = new TransactionScope()) 
{ 
    var db = new dbDataContext(); 

    db.StoredProc(); 
    transaction.Complete(); 
} 

musiałem zadzwonić to tak ...

using (var transaction = new TransactionScope()) 
{ 
    var db = new dbDataContext(); 

    db.StoredProc().ToList(); 
    transaction.Complete(); 
} 

W tym przykładzie ToList() może być dowolna metoda, która powoduje nondeferred LINQ natychmiast ocenić wynik.

Zakładam, że dzieje się tak, ponieważ LINQs leniwa (odroczona) natura nie gra dobrze z momentem transakcji, ale to tylko domysły. Jeśli ktokolwiek mógłby rzucić więcej światła na ten temat, chciałbym o tym usłyszeć.

Powiązane problemy