myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE
   » Gadget für Windows
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Datentechnologien » Zugriff auf die durch eine Transaction gesperrten Daten
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Zugriff auf die durch eine Transaction gesperrten Daten

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
alexander_
myCSharp.de-Mitglied

Dabei seit: 04.09.2009
Beiträge: 15


alexander_ ist offline

Zugriff auf die durch eine Transaction gesperrten Daten

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

verwendetes Datenbanksystem: <SQL Express 2008>
VS 2008 C# mit LINQ to SQL

Hallo,
ich habe folgendes Problem.

Mein Programm besteht aus einem UI und einem Background Thread.

Der Background schreibt kontinuierlich Messdaten in die Datenbank (Messdaten Tabelle) (Dies habe ich über eine Transaction gelößt).

Auf der UI hat der User die Möglichkeit sich die Messdaten anzeigen zu lassen.

Allerdings kann er die Daten nicht anzeigen während die Transaction offen ist.

Ich hätte gerne, dass aus der MessdatenTabelle alle Daten angezeigt werden, die nicht von der Transaction betroffen sind.
Wenn ich aber die Tabelle abfrage laufe ich nur in ein Timeout...

Gibts eine Möglichkeit in der LINQ Abfrage zu sagen, er soll nur nicht gesperrte Daten ausgeben?

Dank für alle Hilfe
Alexander
15.01.2010 12:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.559
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Alexander

Standardmäßig werden nur die Zeilen gelockt die neu geschrieben oder aktualisiert werden. Wenn deine Abfrage diese Daten nicht beinhaltet sollte normalerweise ein Ergebnis zurückgeliefert werden. Ausnahme ist hierbei jedoch Lock Escalation. Hier ein Artikel von Adam Machanic zu dem Thema:
 SQL Server 2008: Lock Escalation, INSERTs, and a Potential Bug

Ansonsten gäbe es theoretisch(!!!) die Möglichkeit mit SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED zu arbeiten. Davon rate ich aber dringendst ab!

Der einfache korrekte Ansatz wäre hier einfach den Background Thread nicht die ganze Zeit mit der gleichen Transaktion arbeiten zu lassen sondern diese alle paar Sekunden zu comitten. Damit kann das parallel abgesetzte SELECT zurückgeliefert werden und alles ist valide.

Ein anderer Weg wäre den Background Thread in eine Staging-Tabelle statt in die eigentliche Zieltabelle schreiben zu lassen und die Daten erst am Ende über eine Bulk-Operation in die Zieltabelle zu übertragen.

Frage:
Welche Datenmengen importiert der Background Thread denn, dass der so lange braucht?

Grüße
Flo
15.01.2010 12:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
alexander_
myCSharp.de-Mitglied

Dabei seit: 04.09.2009
Beiträge: 15

Themenstarter Thema begonnen von alexander_

alexander_ ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

...die Daten kommen von einer Messmaschine, wobei an dieser nicht exakt die Dauer einer Messfahrt definiert ist.

Eigentlich wollte ich die Transaction nutzen, damit nicht vor dem Ende der Messung auf die zugehöirgen Daten zugegriffen werden kann.

Wonach könnte ich die Abfrage filtern, damit nicht die Daten, die momentan geschrieben werden (gesperrt sind), Teil der Abfrage sind.
Ich weiss ja nicht auf welche Datensätze geschrieben wird...

Grüsse
Alexander
15.01.2010 13:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.559
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Alexander

Kommt drauf an. Wie schon gesagt, vielleicht einfach mit einer Staging-Tabelle arbeiten.

Je nach Menge der Daten kannst du die in dem Worker-Thread puffern und über eine Bulk-Operation auf einmal in die Tabellen schreiben. Die Performance bei Bulk-Operationen ist dabei so hoch dass es den Client nicht stören sollte. Hierzu kannst du die Daten entweder die SqlBulkCopy Klasse verwenden welche auf BCP aufsetzt, oder Table-Valued Parameter (TVPs) verwenden. Zu TVPs habe ich vor ein paar Monaten einige Tests gemacht und komme dabei mit 400.000 Datensätzen auf eine Laufzeit von 7 Sekunden. Siehe:
 Table-Valued Parameters - A Performance Comparison

Zuletzt kannst du noch mit TRANSACTION LEVEL SNAPSHOT arbeiten. Das erfordert in deiner aktuellen Implementierung keine Anpassungen, ist aber teuer für den SQL Server da er alle Requests kopieren muss. Dazu muss über ALTER DATABASE Sandbox SET ALLOW_SNAPSHOT_ISOLATION OFF erstmal Snapshot auf der Datenbank erlaubt werden und danach über SET TRANSACTION ISOLATION LEVEL SNAPSHOT; die entsprechende Transaktion in den Snapshot-Modus versetzt werden. Allerdings kann ich dir hier jetzt nicht sagen wie du das in deinem O/R-Mapper aktivieren kannst.

Grüße
Flo
15.01.2010 14:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
alexander_
myCSharp.de-Mitglied

Dabei seit: 04.09.2009
Beiträge: 15

Themenstarter Thema begonnen von alexander_

alexander_ ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

hab die TVPs mal überflogen, klingt echt vielversprechend (leider keine Linq 2 SQL Unterstützung).

Gibt es eine Möglichkeit, dass mir beim Lesen nur aller Daten der Tabelle nur die angezeigt werden, welche "commited" sind und die anderen weggelassen werden?

so siehts im Moment aus

C#-Code:
li_messungen = (from m in rohdatendc.Messungen
                                where (m.FKTypNummerPK == iPK)
                                select
                                    new T_Messungen(m.PK, m.UNI, m.Timestamp, ....).ToList();

...
ich möchte, dass mir nur die angezeigt werden, die commited sind
(die halbfertigen soll er nicht anzeigen)

Gruß alex
15.01.2010 18:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.559
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Nur weil's LINQ2SQL nicht kann heißt das ja nicht dass man's nicht machen kann...

Anyway...
Wie schon gesagt, du musst das Transaction-Level auf Snapshot stellen oder stagen.

Grüße
Flo
15.01.2010 18:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Jahre.
Der letzte Beitrag ist älter als 4 Jahre.
Antwort erstellen


© Copyright 2003-2014 myCSharp.de-Team. Alle Rechte vorbehalten. 02.10.2014 12:25