2016-07-25 12 views
1

Vorbereiten einer Anwendung, die von ungefähr 40 Benutzern im Büro mit lokalem SQL Server im lokalen Netzwerk verwendet wird. Anwendung in VB.NET entwickelt. Ich habe bereits einige Dokumentationen gelesen, möchte aber direkt von Ihrer Seite etwas über den Zugriff auf Daten erfahren.Zugriff auf mehrere SQL Server-Datenbanken

Dies ist eine Winforms-App und ich frage mich, ob Transaktionen, die ich gerade benutze gerade genug Daten zu schützen, wenn ein Benutzer einige Daten verwendet und andere es in der gleichen Zeit ändert, würde Transaktion schützen es? Kann mir jemand kurz erklären, wie es ist?

Beispiel für SQL-Transaktion verwenden, die ich in meiner Anwendung

Dim result As Boolean = True 
Dim strcon = New AppSettingsReader().GetValue("ConnectionString", GetType(String)).ToString() 
Using connection As New SqlConnection(strcon) 
    '-- Open generall connection for all the queries 
    connection.Open() 
    '-- Make the transaction. 
    Dim transaction As SqlTransaction 
    transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted) 
    Try 
     For Each sentId In pSentsId 
      '-- Insert aricle to Article's table (T_Artikel) and get inserted row id to use it in other queries 
      Using cmd As New SqlCommand("INSERT INTO T_Sentence_SubSec_SecKatSubKat_SubSubKat (FK_Sentence_ID, FK_SubSec_SecKatSubKat_SubSubKat) VALUES (@FK_Sentence_ID, @FK_SubSec_SecKatSubKat_SubSubKat)", connection) 
       cmd.CommandType = CommandType.Text 
       cmd.Connection = connection 
       cmd.Transaction = transaction 
       cmd.Parameters.AddWithValue("@FK_Sentence_ID", sentId) 
       cmd.Parameters.AddWithValue("@FK_SubSec_SecKatSubKat_SubSubKat", SubSec_SecKatSubKat_SubSubKat) 
       cmd.ExecuteScalar() 
      End Using 
     Next 
     transaction.Commit() 
    Catch ex As Exception 
     result = False 
     '-- Roll the transaction back. 
     Try 
      transaction.Rollback() 
     Catch ex2 As Exception 
      ' This catch block will handle any errors that may have occurred 
      ' on the server that would cause the rollback to fail, such as 
      ' a closed connection. 
      'Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType()) 
      'Console.WriteLine(" Message: {0}", ex2.Message) 
     End Try 
    End Try 
End Using 
Return result 
+3

Sie erstellen 'SqlCommand' in jeder Schleife. Das ist schlechte Praxis. Erstelle 'SqlCommand' einmal und füge Parameter außerhalb der Schleife hinzu. Setze Parameterwerte und ** 'ExecuteNonQuery' ** in der Schleife. Fangen Sie zunächst 'SqlException' ein. –

+1

Es ist nicht viel wert, eine einzelne INSERT-Anweisung in eine Transaktion einzufügen. Es gibt bereits eine implizite Transaktion beim Einfügen von Daten. Ich denke, was Sie fragen, ist Nebenläufigkeit oder möglicherweise Deadlock-Probleme. Die Verwendung einer Transaktion um eine Insert-Anweisung herum wird dort nicht viel bewirken. Als Randnotiz sollten Sie vorsichtig sein, AddWithValue in Pass-Through-Abfragen wie folgt zu verwenden. Der Datentyp wird manchmal falsch interpretiert. http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-ready/ –

+0

Ich glaube, das läuft, wenn ein anderer Benutzer einen Datensatz mit den gleichen Schlüsselwerten eingefügt hat , dann würde es auslösen (* think * dbConcurrencyException). Wie geschrieben, sollte Ihr Ausnahmebehandler ausgelöst und zurückgesetzt werden, aber dies ist möglicherweise nicht das, was Sie vorhaben. –

Antwort

1

Es gibt zwei Versionen nach Ihren Geschäftsregeln.
A) Alle Einsätze sind erfolgreich oder alle Fehler.

Dim result As Boolean = True 
Dim strcon = New AppSettingsReader().GetValue("ConnectionString", GetType(String))'.ToString()'no need. It is already **String** 
Using connection As New SqlConnection(strcon) 
    ''//--Following 2 lines are OK 
    ''//--Using cmd As New SqlCommand("INSERT INTO T_Sentence_SubSec_SecKatSubKat_SubSubKat (FK_Sentence_ID, FK_SubSec_SecKatSubKat_SubSubKat) VALUES (@FK_Sentence_ID, @FK_SubSec_SecKatSubKat_SubSubKat)", connection) 
    ''//--cmd.CommandType = CommandType.Text 
    ''//--but these two are better 
    Using cmd As New SqlCommand("dbo.T_Sentence_SubSec_SecKatSubKat_SubSubKat_ins ", connection) 
    ''//-- Insert aricle to Articles table (T_Artikel) and get inserted 
    ''//--row id to use it in other queries 
    cmd.CommandType = CommandType.StoredProcedure 
    ''//-- Open generall connection for all the queries 
    ''//--open connection in try block 
    ''//--connection.Open() 
    ''//-- Make the transaction. 
    ''//--Dim transaction As SqlTransaction 
    ''//--transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted) 
    Try 
     connection.Open() 
     cmd.Transaction = connection.BeginTransaction() 
     cmd.Parameters.Add("@FK_Sentence_ID", SqlDbType.Int) ''//--or whatever 
     cmd.Parameters.Add("@FK_SubSec_SecKatSubKat_SubSubKat", SqlDbType.Int) 

     For Each sentId In pSentsId 
      cmd.Parameters("@FK_Sentence_ID").Value = sentId 
      cmd.Parameters("@FK_SubSec_SecKatSubKat_SubSubKat").Value = SubSec_SecKatSubKat_SubSubKat 
      cmd.ExecuteNonQuery() ''//--returns rows affected. We do not use result 
     Next 
     ''//--everything is OK 
     cmd.Transaction.Commit() 
    Catch ex as SqlException 
     result = False 
     ''//--SqlException is more informative for this case 
     If cmd.Transaction IsNot Nothing 
     cmd.Transaction.Rollback 
     ''//--extra try...catch if you wish 
     End If 
    Catch ex As Exception 
     result = False 
     ''//-- Roll the transaction back. 
     Try 
      cmd.Transaction.Rollback() 
     Catch ex2 As Exception 
      ''// This catch block will handle any errors that may have occurred 
      ''// on the server that would cause the rollback to fail, such as 
      ''// a closed connection. 
      ''//Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType()) 
      ''//Console.WriteLine(" Message: {0}", ex2.Message) 
     End Try 
    Finally 
     If connection.State <> Closed 
     connection.Close() 
     End If 
    End Try 
    End Using''//cmd 
End Using''//connection 
Return result 

B) Jeder Einsatz ist unabhängig. Verwenden Sie keine Gesamttransaktion. Fügen Sie try...catch innerhalb for Schleife hinzu.

Verwandte Themen