NET 2: ADO.NET Thema Lektion 8 und 9
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
.NET 2: ADO.NET .NET Framework .NET Core?! Es wird versucht, jeweils darauf hinzuweisen, falls Unterschiede bekannt sind…
ADO.NET Themen zu ADO.NET: 1. ADO.NET Basics 2. Data Provider Nächste Woche: 3. DataReader (Anwendung) 4. DataSet 5. LINQ to SQL 6. Entity Framework 7. Informationssicherheit
1. ADO.NET Basics
https://docs.microsoft.com/en-us/dotnet/api/system.data?view=net-6.0
https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/1. ADO.NET Basics
Was ist ADO.NET?
• Daten-Zugriffs-Technology/Services, direkteste Methode des Datenzugriffs
• Eine "Evolution" der ActiveX Data Objects (ADO) Technologie
• Zugriff auf relationale, XML und andere Datenstrukturen
• .NET Framework: Teilmenge der Klassen in System.Data
• .NET Core: NuGet-Package System.Data.SqlClient (SQL Server),
mit Ausnahme von Datasets und verwandten Typen (2019)1. ADO.NET Basics Grunsätzliche Verwendung von ADO.NET: 1. DataReader Abrufen eines read-only, forward-only stream von Daten (direkter Pfeil ganz recht) 2. DataSet: Sammlung von DataTables, bestehend aus Zeilen und Spalten, Primärschlüssel, Fremdschlüssel, Constraints, etc. 3. LINQ to SQL Abfragen gegen ein Objekt- modell, das auf relationale DBMS abgebildet wird, ohne intermediäres, konzeptionelles Modell. 4. Entity Framework Object-relational mapper (O/RM)
1. ADO.NET Basics
Data Provider
Verbinden mit einer "Datenbank", Ausführen von Befehlen und Abrufen von
Ergebnissen. In .NET Framework enthalten sind Data Provider für:
1. SQL Server
2. ODBC
3. OLE DB Da verschiedene Datenspeichertechnologien
unterschiedliche Fähigkeiten haben können, kann
4. ORACLE
nicht jeder Provider jede mögliche Schnittstelle
5. EntityClient implementieren.
6. SQL Server Compact
.NET Core unterstützt den SQL
Server, ODBC und OleDB.
Es hat weitere NuGet-Packages
für andere DBs (Umfang
unklar).
Der EntityClient wird durch das
EntityFramework verwendet und
basiert auf anderen Providern.
SQL Server Compact ist
deprecated (2013, Support bis
2021, nur Framework).1. ADO.NET Basics
Data Provider in .NET Core (NuGet-Package)
NuGet-Package für SqlClient
in .NET Core
(dieses ist nur für den SQL Server)1. ADO.NET Basics Data Provider Oracle (NuGet-Package)
2. Data Provider: Hauptkomponenten
4 Hauptelemente eines Data-Provider (7 weitere folgen anschliessend):
1. Connection Stellt eine Verbindung zu einer bestimmten Datenquelle her.
2. Command Führt einen Befehl gegen eine Datenquelle aus. Exponiert
Parameter und kann in einer Transaktion ausgeführt werden.
3. DataReader Liest einen schreibgeschützten Datenstrom aus einer
Datenquelle.
4. DataAdapter Liest eine Menge von Tabellen, füllt diese in ein DataSet und
speichert Änderungen.2. Data Provider: Hauptkomponenten
4 Hauptelemente eines Data-Provider (7 weitere folgen später):
1. Connection Stellt eine Verbindung zu einer bestimmten Datenquelle her.
2. Command Führt einen Befehl gegen eine Datenquelle aus. Exponiert
Parameter und kann in einer Transaktion ausgeführt werden.
3. DataReader Liest einen schreibgeschützten Datenstrom aus einer
Datenquelle.
4. DataAdapter Liest eine Menge von Tabellen, füllt diese in ein DataSet und
speichert Änderungen.2. Data Provider: Connection
Connection (implementiert IDbConnection-Interface)
Jeder Data-Provider, der in .NET inbegriffen ist, hat ein spezifisches
DbConnection-Objekt, z.B.:
• SQL Server: SqlConnection Klasse (System.Data.SqlClient)
• OLE DB: OleDbConnection Klasse (System.Data.OleDB)
• ODBC: OdbcConnection Klasse (System.Data.Odbc)
• Oracle: OracleConnection Klasse (Framework: System.Data.OracleClient/
Core: Oracle.DataAccess.Client)
public SqlConnection ();
public SqlConnection (string connectionString);
public SqlConnection (string connectionString, System.Data.SqlClient.SqlCredential cred);
using System.Data.SqlClient;
SqlConnection connection = new SqlConnection(
"Data Source=(local);Initial Catalog=DAB1;Integrated Security=true");
connection.Open();
// do work here
connection.Close();2. Data Provider: Connection
Wird eine Connection nicht geschlossen, werden:
• wertvolle Ressourcen verschwendet und
• allenfalls eine Transaktion nicht geschlossen (Locks bleiben bestehen,
andere User können nicht arbeiten).
Besser:
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(
" Data Source=(local);Initial Catalog=DAB1;Integrated Security=true";))
{
// The connection must still be opened explicitly
connection.Open();
// Do work here...
}
// Connection is closed automatically2. Data Provider: Connection Pool Öffnen einer DB-Connection kann sehr zeitaufwendig sein Idee: Die meisten Verbindungen haben nur eine oder wenige Konfigurationen. Der Pooler lässt aktive Verbindungen am Leben und verwendet diese wieder. Ein Connection Pool ist ein Cache von Datenbankverbindungen für SQL Server, OleDB und Oracle. ODBC hat eigenen Connection Pool.
2. Data Provider: Hauptkomponenten
4 Hauptelemente von Data Providern (7 weitere folgen später):
1. Connection Stellt eine Verbindung zu einer bestimmten Datenquelle her.
2. Command Führt einen Befehl gegen eine Datenquelle aus. Exponiert
Parameter und kann in einer Transaktion ausgeführt werden.
3. DataReader Liest einen schreibgeschützten Datenstrom aus einer
Datenquelle.
4. DataAdapter Füllt ein DataSet und speichert Änderungen.
Command verwendet das
Connection-Objekt zur
Herstellung der Verbindung2. Data Provider: Command • Command (implementiert IDbCommand-Interface). • Führt einen Befehl gegen eine Datenquelle aus. • Exponiert Parameter und kann im Rahmen einer Transaktion aus einer Verbindung heraus ausgeführt werden. Die (abstrakte) Basisklasse für alle Kommandoobjekte ist die Klasse DbCommand. Jeder Data-Provider hat eine eigene Command-Klasse: 1. SqlCommand Klasse (Transact-SQL) 2. OracleCommand Klasse 3. OdbcCommand Klasse 4. OleDbCommand Klasse
2. Data Provider: Command Jedes dieser Command-Objekte hat mehrere Methoden um einen bestimmten Typ eines Kommandos auszuführen: 1. ExecuteReader / ExecuteXMLReader Gibt ein DataReader-Objekt (3. Hauptkomponente des Data-Provider, Details folgen) zurück. Er bietet ungepufferten Stream, z.B. zum Lesen aller Daten einer Tabelle. Der XmlReader ist nur für das SqlCommand-Objekt verfügbar. 2. ExecuteScalar Gibt einzelnen Wert zurück, z.B. zum Bestimmen der Anzahl Datensätze einer Tabelle. 3. ExecuteNonQuery Führt einen Befehl aus, der keine Daten zurückgibt, z.B. Einfügen, Löschen oder Ändern eines Datensatzes, oder eine Stored Procedure.
2. Data Provider: Command Jedes Command-Objekt legt mit dem CommandType fest, wie der Command interpretiert werden muss: 1. Text (Default) Ein SQL-Befehl (mit oder ohne Parameter). 2. StoredProcedure Der Name der Stored Procedure. Über die Parameter eines Befehls kann auf Ein- und Ausgabeparameter zugegriffen werden. 3. TableDirect Nur mit OleDbCommand, alle Datensätze einer Tabelle.
2. Data Provider: Command Beispiel
public SqlCommand ();
public SqlCommand (string cmdText);
public SqlCommand (string cmdText, System.Data.SqlClient.SqlConnection connection);
public SqlCommand (string cmdText, System.Data.SqlClient.SqlConnection connection,
System.Data.SqlClient.SqlTransaction transaction);
Der CommandType
using (SqlConnection connection = ist hier Text (Default).
new SqlConnection("Data Source=(local);Initial Catalog=DAB1;Integrated Security=true"))
{
// Create the command, the SQL-Statement and set its properties and parameters.
using (SqlCommand command = new SqlCommand(
"INSERT INTO L (LNR, LName, Status, Stadt) VALUES (@LNR, @LName, @Status, @Stadt)",
connection))
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("@LNR", "ZHAW");
command.Parameters.AddWithValue("@LName", "Zürcher FH");
command.Parameters.AddWithValue("@Status", 4);
command.Parameters.AddWithValue("@Stadt", "Winterthur");
// Open the connection and execute the reader.
connection.Open();
int rowsAffected = command.ExecuteNonQuery(); Parameter verhindern
connection.Close(); SQL-Injection.
}
} ExecuteNonQuery: Führt
einen Befehl aus, der keine
Daten zurückgibt.2. Data Provider: Hauptkomponenten
4 Hauptelemente von Data Providern (7 weitere folgen später):
1. Connection Stellt eine Verbindung zu einer bestimmten Datenquelle her.
2. Command Führt einen Befehl gegen eine Datenquelle aus. Exponiert
Parameter und kann in einer Transaktion ausgeführt werden.
3. DataReader Liest einen schreibgeschützten Datenstrom aus einer
Datenquelle.
4. DataAdapter Füllt ein DataSet und speichert Änderungen.
Wird durch ein
Command-Objekt
erzeugt2. Data Provider: DataReader
• Stellt einen ungepufferten Datenstrom zur Verfügung.
• Gute Wahl für grosse Datenmengen, da Daten nicht zwischengespeichert
werden. Ausschliesslich vorwärts lesen möglich.
• Um Daten mit einem DataReader zu lesen, erstellen Sie eine Instanz des
Command-Objekts und dann einen DataReader, indem Sie
Command.ExecuteReader aufrufen (kein Konstruktor).
Jeder Data Provider hat eine eigenes DataReader Klasse:
1. SqlDataReader Klasse
2. OracleDataReader Klasse
3. OdbcDataReader Klasse
4. OleDbDataReader Klasse
ConnectionPool:
Die Verbindung wird ausschliesslich verwendet. Immer mit Close() schliessen!
public System.Data.SqlClient.SqlDataReader ExecuteReader ();
public System.Data.SqlClient.SqlDataReader ExecuteReader (System.Data.CommandBehavior
behavior);
public System.Xml.XmlReader ExecuteXmlReader ();2. Data Provider: DataReader Beispiel
using (SqlConnection connection = new SqlConnection(connectionString)) {
// Create the command and set its properties.
SqlCommand command = new SqlCommand();
command.Connection = connection;
DataReader zusammen mit
command.CommandText = "SalesByCategory";
command.CommandType = CommandType.StoredProcedure; StoredProcedure verwendet.
// Add one input parameter and set its properties.
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@CategoryName";
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = "Category";
// Add the parameter to the Parameters collection.
command.Parameters.Add(parameter);
// Open the connection and execute the reader.
connection.Open();
using (SqlDataReader reader = command.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
}
} Liest eine Row des Resultats ein.
}
}
DataReader wird geschlossen
(auch im Fehlerfall).2. Data Provider: Hauptkomponenten
4 Hauptelemente von Data Providern (7 weitere folgen später):
1. Connection Stellt eine Verbindung zu einer bestimmten Datenquelle her.
2. Command Führt einen Befehl gegen eine Datenquelle aus. Exponiert
Parameter und kann in einer Transaktion ausgeführt werden.
3. DataReader Liest einen schreibgeschützten Datenstrom aus einer
Datenquelle.
4. DataAdapter Füllt ein DataSet und speichert Änderungen.
Verwendet vier
Command-
Objekte2. Data Provider: DataAdapter
• Hat 4 Properties vom Typ Command:
• SelectCommand: Daten suchen
• InsertCommand: Daten einfügen
• UpdateCommand: Daten ändern
• DeleteCommand: Daten löschen
• Fill(): Daten lesen (gemäss SelectCommand)
• Liest Daten (Mengen von Rows) aus einer Datenquelle und speichert diese im
DataSet (Sammlung von Tabellen/Relationen).
• Update(): Daten ändern (gemäss Insert-, Update- und DeleteCommand)
• Speichert Änderungen am DataSet in die Datenquelle.
Jeder Data Provider hat eine eigene DataAdapter Klasse:
1. SqlDataAdapter Klasse
2. OracleDataAdapter Klasse
3. OdbcDataAdapter Klasse
4. OleDbDataAdapter Klasse2. Data Provider: DataAdapter Fill()
Beispiel: Fügt Zeilen ins DataSet hinzu (gemäss SelectCommand):
public SqlDataAdapter ();
public SqlDataAdapter (System.Data.SqlClient.SqlCommand selectCommand);
public SqlDataAdapter (string selectCommandText, System.Data.SqlClient.SqlConnection
selectConnection);
Erzeugt den DataAdapter.
// Create the data adapter and the select command.
SqlDataAdapter customerAdapter = new SqlDataAdapter();
customerAdapter.SelectCommand = new SQLCommand("SELECT * FROM dbo.Customers", connection);
// Create the data set (holding the result). Verknüpft den DataAdapter mit
DataSet customerOrders = new DataSet(); einem Command-Objekt.
// Read the data from the database and output each record.
customerAdapter.Fill(customerOrders, "Customers");
foreach (DataRow customerRow in customerOrders.Tables["Customers"].Rows)
{
Console.WriteLine(customerRow["CustomerID"]);
}
• Wird (wann, wo) hier auf dem DB-Server eine Transaktion verwendet?
• Wenn ja, was ist der Isolations-Level der Transaktion?
• Wie verhält es sich beim DataReader?2. Data Provider: DataAdapter Update()
Für jede Zeile in der Tabelle bestimmt die Methode Update die Art der Änderung und
führt die korrespondierende command-Vorlage (Insert, Update oder Delete) aus.
using (SqlConnection connection = new SqlConnection(connectionString)) {
// Create the data adapter and the select command.
SqlDataAdapter categoryAdpater = new SqlDataAdapter( Adapter erstellen
"SELECT CategoryID, CategoryName FROM Categories", connection);
// Create the update command.
categoryAdpater.UpdateCommand = new SqlCommand( Update-Command erstellen
"UPDATE Categories SET CategoryName = @CategoryName " +
"WHERE CategoryID = @CategoryID", connection);
// Add the parameters for the UpdateCommand.
categoryAdpater.UpdateCommand.Parameters.Add( Parameter erstellen
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
SqlParameter parameter = categoryAdpater.UpdateCommand.Parameters.Add(
"@CategoryID", SqlDbType.Int);
parameter.SourceColumn = "CategoryID"; Parameter befüllen
parameter.SourceVersion = DataRowVersion.Original;
// Load the data from the DB into the table of the dataset
DataTable categoryTable = new DataTable();
categoryAdpater.Fill(categoryTable);
// Change the value of the attribute CategoryName of the first row (in memory)
DataRow categoryRow = categoryTable.Rows[0];
categoryRow["CategoryName"] = "New Beverages";
// Propagate all changes to the DB
Alle geänderten Daten-
categoryAdpater.Update(categoryTable); sätze in DB speichern
}2. Data Provider: Weitere Elemente
4 Hauptelemente von Data Providern (7 weitere folgen später):
1. Connection Stellt eine Verbindung zu einer bestimmten Datenquelle her.
2. Command Führt einen Befehl gegen eine Datenquelle aus. Exponiert
Parameter und kann in einer Transaktion ausgeführt werden.
3. DataReader Liest einen schreibgeschützten Datenstrom aus einer
Datenquelle.
4. DataAdapter Füllt ein DataSet und speichert Änderungen.2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. DbExecption Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. DbExecption Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: Transaction • Eine Transaktion besteht aus einem einzelnen Befehl oder einer Gruppe von Befehlen, die als Ganzes (ACID) ausgeführt werden. • Wenn es mehrere Tabellen in derselben DB / Server betrifft, dann bieten Stored Procedures bessere Performance. • Lokale Transaktion: Single-phase Commit - Transaktion direkt von der DB verarbeitet. Die Transaktion wird von der DB «kontrolliert». • Verteilte Transaktion: Two-phase Commit - Transaktionen, die verschiedene Ressourcenmanager betreffen, wie z.B. eine Transaktion mit SQL Server und Oracle. • Transaktionen, können die Parallelität verringern, wenn Sperren lange gehalten werden. Halten Sie daher Transaktionen so kurz wie möglich. • Was passiert, wenn eine Sperre nicht freigegeben wird?
2. Data Provider: Local Transaction
Jeder Data Provider hat eine eigene Transaction Klasse:
1. SqlTransaction Klasse
2. OracleTransaction Klasse
3. OdbcTransaction Klasse
4. OleDbTransaction Klasse
public System.Data.OleDb.OleDbTransaction BeginTransaction ();
public System.Data.OleDb.OleDbTransaction BeginTransaction (System.Data.IsolationLevel
isolationLevel);
// Start a local transaction.
SqlTransaction sqlTransaction = connection.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection.CreateCommand(); Start der Transaktion.
command.Transaction = sqlTransaction;
// execute some commands...
...
// Commit the transaction.
sqlTransaction.Commit();
Ende der Transaktion.2. Data Provider: Local Transaction
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
// Start a local transaction.
SqlTransaction sqlTransaction = connection.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection.CreateCommand();
command.Transaction = sqlTransaction;
try { Die SQL-Statements des command-Objekts
// Execute two separate commands. warden innerhalb dieser Transaktion durchgeführt.
command.CommandText = "INSERT INTO Production.ScrapReason (Name) VALUES ('Wrong size')";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO Production.ScrapReason (Name) VALUES ('Wrong color')";
command.ExecuteNonQuery();
// Commit the transaction.
sqlTransaction.Commit(); Transaktion wird geschlossen (Locks freigegeben).
Console.WriteLine("Both records were written to database.");
}
catch (Exception ex) {
// Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message);
try {
// Attempt to roll back the transaction.
sqlTransaction.Rollback();
} Transaktion wird zurückgesetzt (Locks freigegeben).
catch (Exception exRollback) {
// Throws an InvalidOperationException if the connection is closed or
// the transaction has already been rolled back on the server.
Console.WriteLine(exRollback.Message);
}
}
}2. Data Provider: Local Transaction
Anstelle der Klasse Transaction kann auch die Klasse TransactionScope
(System.Transactions) verwendet werden (empfohlen durch MS):
public TransactionScope ();
public TransactionScope (System.Transactions.Transaction transaction);
Und viele mehr...
// Create the TransactionScope to execute the commands, guaranteeing
// that all commands can commit or roll back as a single unit of work.
using (TransactionScope transactionScope = new TransactionScope()) {
using (SqlConnection connection = new SqlConnection(connectString)) {
// Opening the connection automatically enlists it in the TransactionScope
connection.Open();
...
// Create the SqlCommand object.
SqlCommand command = new SqlCommand(commandText, connection);
...
}
// The Complete method commits the transaction. If an exception has been thrown,
// complete is not called and the transaction is rolled back.
transactionScope.Complete();
}
Transaktion wird geschlossen
(Locks freigegeben).2. Data Provider: Local Transaction
// Create the TransactionScope to execute the commands, guaranteeing
// that both commands can commit or roll back as a single unit of work.
using (TransactionScope scope = new TransactionScope()) {
using (SqlConnection connection = new SqlConnection(connectString)) {
// Opening the connection automatically enlists it in the
connection.Open();
// Create the SqlCommand object and execute the first command.
SqlCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
command.ExecuteNonQuery();
}
// The Complete method commits the transaction. If an exception has been thrown,
// Complete is not called and the transaction is rolled back.
scope.Complete();
}
• Rollback ist nicht notwendig, wird automatisch ausgelöst, falls Fehler
auftritt.2. Data Provider: Distributed Transaction
• Sollen mehrere unabhängig DBMS eine gemeinsame Transaktion
durchführen spricht man von einer verteilten Transaktion.
• Der Two Phase Commit (Zwei-Phasen-Commit) regelt die
Synchronisation der Transaktionen über mehrere DBMS (cross-
database) hinweg (nicht verwechseln mit Zwei-Phasen-Sperr-
Protokoll).
• Diese Synchronisation ist Aufwändig und kann Ressourcen lange Zeit
sperren…
• Verteilte Transaktionen sollten nach Möglichkeit NICHT verwendet
werden -> andere Lösungen suchen.2. Data Provider: Distributed Transaction
2-Phasen-Commit-Protokoll im Normalbetrieb
Client Transaction
Manager DBMS 1 DBMS 2
Wiederherstellbarkeit muss
1. Phase Commit
Prepared Sichergestellt werden:
Log Satz Log-Daten und Prepared-Satz
in Log-Datei ausschreiben.
Anschliessend Ready-Nachricht
Log Prepared senden.
Satz
Commit Transaction Manager schreibt
Satz Log Commit-Satz in Log-Datei.
2. Phase Commit
Log Commit
Satz Commit-Satz wird in Log-Datei
geschrieben, Sperren werden
frei gegeben. Anschliessend
Log Commit
Satz ACK-Nachricht senden.
Ende
Satz Log2. Data Provider: Distributed Transaction
Fehler: Wir betrachten als Beispiel den (unerwarteten) Neustart des
DBMS 2 (siehe vorangehende Folie).
4 mögliche Fälle für abgebrochene Transaktionen des DBMS (nicht
Transaktions-Manager):
1. Commit in der 2. Phase erfolgt: Commit-Satz im Log von DBMS2.
Redo-Recovery um Änderungen zu wiederholen, die noch nicht in die
physische Datenbank gelangten.
2. Abbruch in der 2. Phase durch Koordinator: Abort-Satz im Log von DBMS2.
Undo-Recovery um Änderungen zurückzunehmen, die bereits in die
physische Datenbank gelangten.
3. Erst 1. Phase erfolgreich abgeschlossen: Prepared-Satz im Log.
Globales Commit-Ergebnis beim Manager/Koordinator nachfragen und
Transaktion entsprechend abschliessen.
4. Abbruch in der 1. Phase: Kein Commit-, Abort- oder Prepared-Satz im Log.
Transaktion abbrechen (Undo-Recovery), da Commit-Protokoll noch nicht
begonnen wurde.2. Data Provider: Distributed Transaction
Technische Grundlage für verteilte Transaktionen im C# und SQL Server
Umfeld:
• X/Open XA (kurz XA, abgeleitet von eXtended Architecture): Von The
Open Group (> 600 Mitglieder) 1991 spezifizierter Informatik-
Standard für Distributed Transaction Processing (nicht nur für DBMS).
• Der Distributed Transaction Coordinator (MS DTC), ist ein
Systemdienst auf Windows Betriebssystemen, zur Koordination
atomarer Operationen. Er implementiert den XA Standard.
• Der SQL Server und C# benötigen für verteilte Transaktionen den
MS DTC.2. Data Provider: Distributed Transaction Wie muss MS DTC und SQL Server für verteilte Transaktionen eingerichtet werden? 1. MS DTC muss mittels Component Services Anwendung (Komponentendienste, comexp.msc) konfiguriert werden (Properties).
2. Data Provider: Distributed Transaction
2. In der Standardeinstellung führt ein nicht schwerwiegender Fehler, der
durch eine Anweisung innerhalb einer Transaktion ausgelöst wird,
nicht automatisch zu einem Rollback (erst ab fatal = severity 19 and
above).
Diese Einstellung sollte auf ON (je DB) gesetzt werden:
SET XACT_ABORT { ON | OFF }
Es lohnt sich auch für nicht verteilte Transaktionen scharf zu
überlegen, ob XACT_ABORT aktiviert sein sollte.
Ein Foreign-Key-Fehler hat z.B. severity 16. Bei OFF würde die
Transaktion in diesem Fall nicht abgebrochen, sondern zur nächsten
Anweisung übergehen.2. Data Provider: Distributed Transaction NUN sind zwei Anwendungsfälle möglich: 1. Verteilte Transaktion auf dem SQL Server 2. Verteilte Transaktion in C#
2. Data Provider: Distributed Transaction
1. Fall: Verteilte Transaktion auf dem SQL Server
• Auf jedem Server muss der MS DTC aktiviert sein.
• Die SQL Server müssen als Linked Server beim SQL Server des
Transactions Managers eingetragen sein.
• Die Transaktion muss in T-SQL als verteilte Transaktion gekennzeichnet
werden:
Resource
BEGIN DISTRIBUTED { TRAN | TRANSACTION } Manager
[ transaction_name | @tran_name_variable ] Transaction
Manager
MS DTC
SQL
• Es können auch andere DBMS Server
Local
eingebunden werden, die Trans.
MS DTC
XA-Compliant sind. SQL
Server
Client
• Aus Sicht des C#-Data Providers Local
Trans.
MS DTC
ist es eine lokale Transaktion. SQL
Server
Resource
• Funktioniert auch für gespiegelt Manager Local
Trans.
SQL Server Datenbanken Commits or rolls Resource
(Allways-on Feature) back via 2PC Manager2. Data Provider: Distributed Transaction
2. Fall: Verteilte Transaktion in C#
• Auch verteilte Transaktionen werden über die API im Namensraum
System.Transactions verwaltet: TransactionScope (empfohlene
Methode)
• TransactionScope verwendet den Lightweight Transaction Manager
(LTM), erst wenn eine verteilte Transaktion "entsteht" wird automatisch
auf den Distributed Transaction Coordinator (MS DTC) gewechselt.
→ Eine Lightweigt Transaction ist eine lokale Transaktion, die bei
Bedarf (sobald eine Connection zu einem anderen Server hergestellt
wird) zu einer verteilten Transaktion wird.
• Funktioniert auch mit der Transaction-Klasse. Sobald ein Command in
die Transaktion aufgenommen wird, die einen anderen Server
verwendet (command.Transaction = sqlTransaction;).2. Data Provider: Distributed Transaction
// Create the TransactionScope to execute the commands, guaranteeing
// that both commands can commit or roll back as a single unit of work.
using (TransactionScope scope = new TransactionScope()) {
using (SqlConnection connection1 = new SqlConnection(connectString1)) {
// Opening the connection automatically enlists it in the
// TransactionScope as a lightweight transaction.
connection1.Open();
// Create the SqlCommand object and execute the first command.
SqlCommand command1 = new SqlCommand(commandText1, connection1);
returnValue = command1.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command1: {0}", returnValue);
// If you get here, this means that command1 succeeded. By nesting
// the using block for connection2 inside that of connection1, you
// conserve server and network resources as connection2 is opened
// only when there is a chance that the transaction can commit.
using (SqlConnection connection2 = new SqlConnection(connectString2)) {
// The transaction is escalated to a full distributed transaction when
// connection2 is opened.
connection2.Open();
// Execute the second command in the second database.
SqlCommand command2 = new SqlCommand(commandText2, connection2);
returnValue = command2.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
}
}
// The Complete method commits the transaction. If an exception has been thrown,
// Complete is not called and the transaction is rolled back.
scope.Complete();
}2. Data Provider: Transaction Transaktionen sind ein absolut zentrales Element in der Verarbeitung von Daten. Ein gutes Verständnis der Zusammenhänge ist enorm wichtig. Aufgrund der grossen Bedeutung, gibt es noch viele weitere Aspekte (die wir nicht mehr betrachten), z.B.: • Optimistic Concurrency • Isolation Level • Automatisches (Default) / Manuelles Enlisting von Commands in Transaktionen • TransactionException Klasse • TransactionInformation Klasse • …
2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. DbExecption Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: Command Builder Der DataAdapter hat 4 Properties vom Typ Command: • SelectCommand: Daten suchen • InsertCommand: Daten einfügen • UpdateCommand: Daten ändern • DeleteCommand: Daten löschen Ist das Select-Commando gesetzt, kann der DataAdapter das Select-Kommando ausführen und mit den erhaltenen (Meta-)Daten die Insert-, Update- und Delete- Kommandos automatisch erzeugen. Folgendes muss beachtet werden: • Das Resultat muss aus einer Tabelle bestehen (kein Join) • Das Resultat muss einen Primärschlüssel enthalten • Es wird ein zusätzlicher Round-trip zum SQL-Server erzeugt // Assumes that connection is a valid SqlConnection object and already opened SqlDataAdapter adapter = new SqlDataAdapter( "SELECT * FROM dbo.Customers", connection); adapter.Fill(dataSet, "Customers"); SqlCommandBuilder builder = new SqlCommandBuilder(adapter); ... // generate statements to modify the DataSet builder.GetUpdateCommand();
2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. DbExecption Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: ConnectionStringBuilder
Bietet eine einfache und sichere Möglichkeit, den Inhalt von Connection Strings
zu erstellen und zu verwalten, die von der Klasse SqlConnection (SQL Server!)
verwendet werden.
public SqlConnectionStringBuilder();
public SqlConnectionStringBuilder(string connectionString);
SqlConnectionStringBuilder builder =
new SqlConnectionStringBuilder("server=(local);user id=ab;" +
"password=Winter1234;initial catalog=AdventureWorks");
// Now that the connection string has been parsed, you can work with individual items.
builder.Password = "new@1Password";
// You can refer to connection keys using strings, as well.
builder["Server"] = ".";
builder["Connect Timeout"] = 1000;
builder["Trusted_Connection"] = true;
Console.WriteLine(builder.ConnectionString);2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. DbExecption Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: Parameter • Command-Objekte verwenden Parameter, um Werte an SQL-Anweisungen oder Stored Prozedures zu übergeben, die eine Typprüfung und Validierung ermöglichen. • Verbessern die Leistung, da sie dem DBMS helfen, den Befehl mit einem im Cache gespeicherten Execution Plan abzugleichen (Execution Plan Pooling auf dem SQL Server). • Parameter müssen im ParameterDirection-Property: Input, InputOutput, Output oder ReturnValue angeben. • Ein DbParameter-Objekt kann mit seinem Konstruktor oder durch Hinzufügen zur DbParameterCollection erstellt werden (Add-Methode). • Die Syntax (Naming) für Parameter-Platzhalter ist abhängig von der Datenquelle (SQL Server: @, Oracle: :, OleDb & Odbd: ?) • Die Datentypen müssen von C# und zurück konvertiert werden
2. Data Provider: Parameter
public sealed class SqlParameter : System.Data.Common.DbParameter, ICloneable;
static void GetSalesByCategory(string connectionString, string categoryName) {
using (SqlConnection connection = new SqlConnection(connectionString)) {
// Create the command to call a stored procedure and set its properties
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SalesByCategory";
command.CommandType = CommandType.StoredProcedure;
// Add the input parameter, set its properties and add to the collection
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@CategoryName";
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = ;
command.Parameters.Add(parameter);
// Open the connection and execute the reader
connection.Open();
using (SqlDataReader reader = command.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
}
}
else { Console.WriteLine("No rows found."); }
}
}
}2. Data Provider: Parameter
Im Gegensatz zum Befehlstext werden Parameter als literaler Wert und nicht als
ausführbarer Code behandelt. Dies hilft, sich vor "SQL Injection"-Angriffen zu
schützen (SQL Server-Beispiel):
SqlCommand command = new SqlCommand("SELECT * FROM Authentication " +
"WHERE Username = @Username and Password = @Password", connection);
command.CommandType = CommandType.Text;
// Create the first parameter and add it to the collection
SqlParameter userName = new SqlParameter();
userName.ParameterName = "@Username";
userName.Value = txt1.Text;
command.Parameters.Add(userName);
// Create the second parameter and add it to the collection
SqlParameter password = new SqlParameter();
password.ParameterName = "@Password";
password.Value = txt2.Text;
command.Parameters.Add(password);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows) {
Console.WriteLine("{0}", reader[0]);
}
else { errorlbl.Text = "Incorrect username and password"; }2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. DbExecption Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Error-Objekt ist Property of Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: DbExecption
Die Klasse DbException ist die Basisklasse für alle Ausnahmen. Jeder Data
Provider hat eine eigene Exception Klasse:
1. SqlException Klasse
2. OracleException Klasse
3. OdbcException Klasse
4. OleDbException Klasse
try {
// Do work here.
}
catch (SqlException ex) {
for (int i = 0; i < ex.Errors.Count; i++) {
errorMessages.Append("Index #" + i + "\n" +
"Message: " + ex.Errors[i].Message + "\n" +
"Line Number: " + ex.Errors[i].LineNumber + "\n" +
"Source: " + ex.Errors[i].Source + "\n" +
"Procedure: " + ex.Errors[i].Procedure + "\n");
}
Console.WriteLine(errorMessages.ToString());
}
finally {
// Perform cleanup here.
}2. Data Provider: Weitere Elemente 7 weitere Elemente des Data Provider: 1. Transaction Transaktionssteuerung der Befehle. 2. CommandBuilder Erzeugt automatisch Befehlseigenschaften eines DataAdapters. 3. ConnectionStringBuilder Erstellt und Verwaltet ConnectionStrings 4. Parameter Definiert Eingabe-, Ausgabe- und Rückgabewertparameter für Befehle und Stored Procedures. 5. Exception Wird zurückgegeben, wenn ein Fehler in der Datenquelle aufgetreten ist. 6. Error Enthält die Informationen aus einer Warnung oder einem Fehler, die von einer Datenquelle zurückgegeben werden. 7. ClientPermission Zugriff auf Sicherheitsattribute.
2. Data Provider: ClientPermission Die Klasse DbDataPermission stellt sicher, dass ein Benutzer über eine Sicherheitsstufe verfügt, die für den Zugriff auf Daten angemessen ist: 1. SqlClientPermission Klasse 2. OracleClientPermission Klasse 3. OdbcClientPermission Klasse 4. OleDbClientPermission Klasse
Nächste Woche: 1. DataReader 2. DataSet 3. LINQ to SQL 4. Entity Framework
Fragen?
Uff!Sie können auch lesen