Laden...
N
Nuky myCSharp.de - Member
Student Erlangen Dabei seit 23.06.2010 20 Beiträge
Benutzerbeschreibung

Forenbeiträge von Nuky Ingesamt 20 Beiträge

06.12.2011 - 22:53 Uhr

Der Vollständigkeit halber sei erwähnt, dass IPC nur zur Kommunikation zweier Prozesse auf dem selben Computer geeignet ist.
Zu IPC zählen z.B. des net.pipe-Binding von WCF bzw. allgemein Anonymous/NamedPipes in .NET.

Andere Bindings von WCF sind dagegen natürlich, wie gfoidl schon gesagt hat, für die Kommunikation über Internet geeignet 😉

06.12.2011 - 22:01 Uhr

Ich finde nicht, dass READUNCOMITTED ein gutes Vorgehen ist. Schließlich will man meistens auch beim Lesen ein konsistentes Datenbild erhalten.
Mit Ausnahme von Debugging kann ich mir auch kein sinnvolles Szenario für READUNCOMITTED vorstellen, da es ja de facto den ganzen Sinn hinter Transaktionen untergräbt.

Fehlermeldungen anzuzeigen halte ich auch für problemlos. Einer Fehlermeldung geht ja ein Fehler voraus, welcher dazu führen muss, dass die Transaktion abgebrochen und ein Rollback durchgeführt wird.

Um SQL-Deadlocks zu lösen, hat es mir immer geholfen, mir vorzustellen (bzw. aufzuzeichnen), was alles in fraglicher Transaktion passiert und was auf den beteiligten Tabellen gleichzeitig passieren kann.
Häufige Probleme sind, dass der SQL-Server bei manchen Statements die Locks nicht bis zum Ende der Transaktion hält (mit WITH(HOLDLOCK) lösbar) oder Lese- und Schreibvorgänge in der gleichen Transaktion ablaufen.

Zweiteres ist auch bei Dir vorstellbar:
Durch das Select wird ein Readlock auf der Tabelle erzeugt. Folgt in derselben Transaktion nun ein Update/Insert auf der Tabelle, kommt es zum Deadlock, wenn zwei User die selbe Operation gleichzeitig ausführen:
Beide können gleichzeitig aus der Tabelle lesen (das Readlock lässt das zu) und warten dann darauf, dass der jeweils andere das Readlock "löst" um ein Writelock (für das Update/Insert) erzeugen zu können.

Die Lösung für diesen Fall wäre, schon bei der SELECT-Operation ein Schreiblock anzufordern (per WITH(UPDLOCK, HOLDLOCK)).
Und, wie BerndFfm gesagt hat, immer in der gleichen Reihenfolge locken.

Letztendlich solltest du machen was gfoidl gesagt hat: Das Gesamtbild betrachten.

P.S.:
Folgender Artikel beschreibt das Vorgehen, das nötig ist, damit der SQL Server Deadlocks loggt:
http://support.microsoft.com/kb/832524

23.11.2011 - 12:48 Uhr

Eben beim Refactoring eines Projektes gefunden:


lb_RatingCount.Text = WebResources.count + " " + string.Format( "({0})", result.RatingCount ) + " " + WebResources.ratings;

03.11.2011 - 22:48 Uhr

Erstelle dir einen HTTP-Web-Service, der auf die Datenbank zugreift und spreche diesen aus der Windows Phone-Anwendung heraus an.

03.11.2011 - 19:42 Uhr

Ohne den Code genauer anzuschauen:

Ist dein Server beim Testen auf dem selben PC wie der Client?
Wenn ja, ist es nicht verwunderlich, dass die CPU-Auslastung relativ hoch ist. Schließlich wird die Übertragungsgeschwindigkeit nicht durch ein dazwischenliegendes Netzwerk o.ä. sondern einzig und allein durch die Leistungsfähigkeit deines PCs begrenzt.

Bei einer Auslastung von 50% tippe ich auf 2 CPU-Kerne. Dass nur einer davon genutzt wird liegt daran, dass dein Code single-threaded ist.

01.11.2011 - 20:31 Uhr

Wenn er die 50 Inserts in eine Transaktion verpackt und dann irgendwo ein Fehler auftritt, werden alle bereits durchgeführten Inserts rückgängig gemacht.
Ich habe nickys Frage allerdings so verstanden, dass beim Auftreten eines Fehlers (durch Verletzung des Primary Key-Contstraints) alle anderen Statements trotzdem durchgeführt werden sollen.

30.10.2011 - 23:15 Uhr

Also zunächst mal sollte es funktionieren bevor du über Optimierungen nachdenkst.

Abgesehen davon bleibt dir meines Erachtens nur eine Alternative zu Merge:


IF NOT EXISTS( SELECT ID FROM table WHERE column=x )
BEGIN
    INSERT INTO table (column) VALUES (x)
END

Exceptionhandling auf Datenbankebene ist mir nicht bekannt. Und selbst wenn es soetwas gäbe, wäre es schlechtes Design wenn Exceptions Teil des normalen Programmablaufs wären. (Das gilt natürlich auch für try-catch um den c#-code der die Datenbankstatements absetzt)

P.S.: Ich verstehe auch nicht ganz, warum du nicht alle Inserts zusammen an die DB übermittelst, wenn du schon so auf Geschwindigkeit aus bist.

30.10.2011 - 22:59 Uhr

Deine Frage hört sich so an, als könnte dir das Merge-Statement weiterhelfen. Ich kenne es nur aus MSSQL aber auf den ersten Blick funktioniert es in Firebird genauso...

Du würdest dir also eine temporäre Tabelle anlegen, dieser alle 50 Datensätze hinzufügen und dann mit der eigentlichen Zieltabelle mergen.

23.10.2011 - 23:16 Uhr

Das sagt die MySQL-Doku dazu:

Deklaration lokaler Variablen in MySQL

Setzen geht wohl mit "SET".

Ergo sollte folgendes funktionieren:


START TRANSACTION;

DECLARE userid INT

SET @userid = ( 
  SELECT tableUser.id
      FROM tableUser 
        INNER JOIN tableUserName ON tableUserName.userId = tableUser.id
	   WHERE tableUserName.name='Benutzer 2'))

INSERT INTO tableUserName (userId, name, startdate)
VALUES (userid, 'Neuer Benutzername', Now());

COMMIT;

Das herauszufinden hat mich keine 5min gekostet. Das hättest du auch geschafft 😉

23.10.2011 - 22:01 Uhr

Versuchs mal mit nem UpdatePanel außenrum.

23.10.2011 - 01:12 Uhr

WCF unterstützt verteilte Transaktionen. Allerdings muss dafür ein kompatibles Binding verwendet und die Eigenschaft "transactionFlow" auf true gesetzt werden (üblicherweise in der Service-Web.config).

Darüberhinaus gibt es Attribute um das Transaktionsverhalten zu steuern:*[TransactionFlow( TransactionFlowOption.Mandatory/Allowed/NotAllowed )] über den Methoden im Service-Contract *[OperationBehavior( TransactionScopeRequired = true/false )] über der jeweiligen Methodenimplementierung

Bei TransactionFlowOption.Allowed und TransactionScopeRequired = true wird also beispielsweise automatisch eine lokale Transaktion erzeugt, falls keine durch den Aufrufer übergeben wurde (typischerweise über TransactionScope).

In der Persistenzschicht kann man dann einfach über sqlConnection.Enlist(Transaction.Current) an der übergebenen Transaktion teilnehmen.

23.10.2011 - 00:50 Uhr

Ersetze die Fragezeichen durch die Parameterbezeichner (@p1-x).
Ansonsten noch ein Tipp: Benutze aussagekräftige Variablennamen. Ansonsten weißt du selbst in kürzester Zeit nichtmehr, was der Code eigentlich genau macht.

23.10.2011 - 00:43 Uhr

Und wenn du es einfach "auseinanderziehst"?


DECLARE @userid int

SELECT @userid = ( 
  SELECT tableUser.id
      FROM tableUser 
        INNER JOIN tableUserName ON tableUserName.userId = tableUser.id
	   WHERE tableUserName.name='Benutzer 2'))

INSERT INTO tableUserName (userId, name, startdate)
VALUES (@userid, 'Neuer Benutzername', Now());

Achtung: Ob das MySQL-kompatible Syntax ist weiß ich nicht.

23.10.2011 - 00:14 Uhr

Ok, dann sollte folgendes funktionieren:


INSERT INTO tableUserName (userId, name, startdate)
VALUES 
( (SELECT tableUser.id
      FROM tableUser 
        INNER JOIN tableUserName ON tableUserName.userId = tableUser.id
	   WHERE tableUserName.name='Benutzer 2'),
    'Neuer Benutzername',
     Now());

22.10.2011 - 23:35 Uhr

Konsumierst du den Service nur oder kannst du ihn ändern? Wenn zweiteres der Fall ist, rate ich dir, dich über DataContract-Versionierung zu informieren.
Anstatt eine Reihe von Parametern zu übergeben, würdest du dir dabei einen einzigen DataContract definieren, der diese enthält. WCF bietet dabei die Möglichkeit, neue optionale Properties hinzuzufügen und so auch alte Clients weiterhin zu unterstützen.

Ansonsten hast du das Problem, dass du quasi zwei Signaturen für ein und dieselbe Funktion unterstützen willst. Da WCF bzw. SOAP weder Methodenüberladung noch optionale Parameter (bzw. welche mit default-Wert) unterstützt, glaube ich nicht, dass es so funktionieren wird, wie du dir das vorstellst.
Obwohl du "minOccurs=0" angibst, muss der Parameter immer übergeben werden.

22.10.2011 - 23:06 Uhr

Folgendes Statement nennt alle Benutzer, deren Name "Benutzer 2" ist, um, setzt das Feld "startdate" auf das aktuelle Datum und lässt alle anderen Felder unangetastet:

UPDATE [tableUserName] SET name="Neuer Name", startdate=Now() WHERE name="Benutzer 2"
22.10.2011 - 21:18 Uhr

Das Statement macht für mich überhaupt keinen Sinn. Kann es sein, dass du eigtl einen Datensatz aktualisieren willst, anstatt einen neuen in die Tabelle einzufügen?

Wenn ja, schau dir mal das UPDATE-Statement an.

15.10.2011 - 00:23 Uhr

In der Zwischentabelle hast du zwei Foreign-Keys (SpielerId und SpieltagId) sowie einen Primary-Key über diese beiden Felder.
Wie das genau mit Hibernate umzusetzen ist, kann ich dir nicht sagen, da ich mich damit nicht auskenne.
Allerdings sollte das doch mit etwas Doku-Recherche leicht zu lösen sein, oder?!

Falls das an der Frage vorbeiging möchte ich dich bitten, sie etwas genauer zu formulieren.

02.10.2011 - 19:35 Uhr

Distinct kann, wie DESoft bereits geschrieben hat, nur auf das gesamte SELECT-Statement angewendet werden. Daher hole ich mir zuerst alle eindeutigen Namen aus der Tabelle und gebe dieser Abfrage mit "WITH" einen Namen, so dass ich das Ergebnis einfach referenzieren kann.
Aus dieser Ergebnis-"Tabelle" hole ich mir nun alle Einträge und jeweils den ersten Eintrag der Ursprungstabelle, in dem Ursprungstabelle."Name" gleich Ergebnis."Name" ist.

Allerdings solltest du vielleicht die Datenbankstruktur überdenken und dir mal http://de.wikipedia.org/wiki/Normalisierung_%28Datenbank%29 anschauen.

02.10.2011 - 18:05 Uhr

WITH [TempTbl] AS (SELECT DISTINCT Name FROM [MYTABLE])

SELECT [TempTbl].Name, (SELECT TOP 1 Col1 FROM [MYTABLE] WHERE [MYTABLE].Name = [TempTbl].Name) AS Col1, (SELECT TOP 1 Col2 FROM [MYTABLE] WHERE [MYTABLE].Name = [TempTbl].Name) AS Col2 FROM [TempTbl]