Uproszczony zapis using zamyka się wcześniej i nie commituje zmian do bazy

3

To nie jest żaden wyjątek, po prostu te property w obecnym stanie obiektu nie jest obsługiwane. To normalne, że jak przeglądasz listę właściwości obiektu, to połowa z nich rzuca wyjątkami tak, jak na Twoim screenshocie.

0

A nie jest tak, że wykonujesz Commit() poza scopem usinga z transakcją? Wewnętrzny using wykona dispose jako pierwszy i potem dopiero zostanie wywołany dispose na zewnętrznym usingu?

Dawno nie siedziałem w internalach C# ale bym sprawdził jak te dwa kody (jeden z klamrami, drugi bez) wygląda w IL. Może być tak, że kompilator parsując kod i generując z niego IL robi jakiś trick pod spodem który sprawia, że wywołanie commita jest poza zakresem? Najlepiej tak jak napisałem - sprawdzić to u źródła w IL. Ewentualnie potem zdekompilować do C# za pomocą ILSpy albo dotPeeka.

Zawsze byłem nieufny do takich lukrów składniowych, które robią jakieś czary pod spodem tak jak ostatnio to jest modne w ASP.NET Core :) Nie ma to jak klasyczna struktura programu czyli namespace potem class potem metody, pola...

0

A to nie jest tak jak z if-em bez klamerek? Na szybko przeleciałem po przykładach i wszędzie widzę że wewnętrzny using ma zawsze klamry tak jak tu żeby wykonać nie jedną instrukcję ale blok instrukcji.

using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
using (var reader = new StreamReader(stream))
{
    TextBox1.Text = reader.ReadToEnd(); // or whatever
    ...
}

Więc coś jest na rzeczy z tym jak CLR parsuje te usingi do IL-a.

0

@ŁF: Ok, myślałem, że to ma coś wspólnego z tym, że nie działa commit.

@markone_dev: No właśnie wszystko by na to wskazywało, że w miejscu t.Commit() scope z using'a nie istnieje i nie ma jak transakcji zapisać. Pewnie debugowaniem nie da rady tego ogarnąć.

0

@AdamWox:

@markone_dev: No właśnie wszystko by na to wskazywało, że w miejscu t.Commit() scope z using'a nie istnieje i nie ma jak transakcji zapisać. Pewnie debugowaniem nie da rady tego ogarnąć.

Jedynie kompilacja do IL i porównanie outputów.

0

Użyłem dotPeek, bo to akurat miałem zainstalowane i nie dodaje nic po skompilowaniu. Jest identycznie to samo co w kodzie źródłowym - bez klamerek.

1

zmień wersję c# do której dekompiluje do niższej w której nie było jeszcze tego ficzera

0

Wklej cały kod metody który działa i cały kod metody która nie działa (możesz je uprościć, ale sprawdź czy błąd dalej występuje). Na 50% coś pomieszałeś, na 49.9% źle testujesz a na 0.1% dowiemy się czegoś nowego

5

@AdamWox:

screenshot-20230125014016.png

ale pokazujesz to co jest w obiekcie transakcji po jej commicie/rollbacku, no to raczej nie tędy droga, zobacz co tam jest przed robieniem commita.

dodatkowo jeżeli niby debugger nie pomaga, to sobie dodaj debug printki (czy te pętle się faktycznie wykonują) i zobacz logi SQL Servera.

U mnie działa

using var db = new SqlConnection(cs);
db.Open();
using var t = db.BeginTransaction();

if (DateTime.Now.Year >= 2023)
{
    var dp = new DynamicParameters();
    dp.Add("@B", "W");
    dp.Add("@C", "E");
    await db.ExecuteAsync("INSERT INTO TestTable VALUES (@B)", dp, t);
    await db.ExecuteAsync("INSERT INTO TestTable VALUES (@C)", dp, t);
}

t.Commit();

0 użytkowników online, w tym zalogowanych: 0, gości: 0