Discussion:
Snapshot Isolation Level aktivieren unter SQL Express
(zu alt für eine Antwort)
Martin Schönholzer
2006-03-05 22:44:32 UTC
Permalink
Hallo geschätzte Newgroup Mitglieder.

Beim Studium der Neuerungen von ADO 2.0 bin ich
auf den neuen Isolation Level 'Snapshot' gestossen.

Ich habe gelesen, dass dieses Feature explizit aktiviert werden muss, um
genutzt werden zu können. Leider hat sich das auf meiner Express-Version
nicht umsetzen lassen.

Kommando:
für 'myDB' habe ich den Namen meiner SQL Express DB, also den Pfad eingesetzt.
---------------------------------------------
ALTER DATABASE myDB
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE myDB
SET READ_COMMITTED_SNAPSHOT ON
---------------------------------------------
diese Statements konnten erfolgreich ausgeführt werden.
Danach habe ich den Dienst neu gestartet und dennoch erhalte ich:

Fehler beim Zugriff der Snapshotisolationstransaktion auf die 'C:\DOKUMENTE
UND EINSTELLUNGEN\EIGENE DATEIEN\VISUAL STUDIO
2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF'-Datenbank, weil die
Snapshotisolation in dieser Datenbank nicht zulässig ist. Verwenden Sie ALTER
DATABASE, um die Snapshotisolation zuzulassen.

Weiss jemand wie ich dieses Feature unter SQL-Express aktivieren kann?
Besten Dank für eure Inputs.

Gruss: Martin
Elmar Boye
2006-03-06 08:47:45 UTC
Permalink
Hallo Martin,
Post by Martin Schönholzer
Beim Studium der Neuerungen von ADO 2.0 bin ich
auf den neuen Isolation Level 'Snapshot' gestossen.
Ich habe gelesen, dass dieses Feature explizit aktiviert werden muss,
um genutzt werden zu können. Leider hat sich das auf meiner
Express-Version nicht umsetzen lassen.
für 'myDB' habe ich den Namen meiner SQL Express DB, also den Pfad
Pfade werden bei ALTER DATABASE nicht angegeben, nur der logische
Datenbankname. Was hast Du da genau angegeben?
Post by Martin Schönholzer
eingesetzt. ---------------------------------------------
ALTER DATABASE myDB
SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE myDB
SET READ_COMMITTED_SNAPSHOT ON
---------------------------------------------
diese Statements konnten erfolgreich ausgeführt werden.
Danach habe ich den Dienst neu gestartet
Ein Neustart ist dafür nicht erforderlich. Ansonsten sollte obiges reichen.
Weitere Lektüre wäre: http://msdn2.microsoft.com/de-de/library/ms177404.aspx
Post by Martin Schönholzer
Fehler beim Zugriff der Snapshotisolationstransaktion auf die
'C:\DOKUMENTE UND EINSTELLUNGEN\EIGENE DATEIEN\VISUAL STUDIO
2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF'-Datenbank, weil die
Snapshotisolation in dieser Datenbank nicht zulässig ist. Verwenden
Sie ALTER DATABASE, um die Snapshotisolation zuzulassen.
Ich könnte mir vorstellen, dass Du die falsche Datenbank erwischt hast.
Wenn Du mit dem User Instance Feature arbeitest verbinde die Datenbank
mal direkt mit der SQL Server Express Instanz via sp_attach_db und stelle
das Snapshot Feature ein.

Gruss
Elmar
Post by Martin Schönholzer
Weiss jemand wie ich dieses Feature unter SQL-Express aktivieren kann?
Besten Dank für eure Inputs.
Gruss: Martin
Martin Schönholzer
2006-03-06 19:52:03 UTC
Permalink
Hallo Elmar
Erst mal besten Dank für deinen Post und deinen Link.

Lustigerweise ist auf meiner besagten SQL-Express Datenbank der logische
Name identisch mit dem Pfad, also: "C:\DOKUMENTE UND EINSTELLUNGEN\EIGENE
DATEIEN\VISUAL STUDIO 2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF"

Das merke ich daran, dass ich die Datenbank über:
---------------------------------------------------------
Use "C:\DOKUMENTE UND EINSTELLUNGEN\EIGENE DATEIEN\VISUAL STUDIO
2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF"
---------------------------------------------------------
ansprechen kann. (ich tue dies via Management Studio Express)

Eine Query von:
Select * from sys.databases
ergibt das selbe resultat. Ich erhalte die 4 Standard DB's:
master, tempdb, model, msdb und C:\DOKUMENTE UND EINSTELLUNGEN\EIGENE
DATEIEN\VISUAL STUDIO 2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF

Jetzt ganz interessant:
diese Abfrage zeigt ja unter anderem für alle Db's den Wert von der Snapshot
aktivierung: (snapshot_isolation_state_desc). Der Wert ist dort auf ON.

Dennoch kann ich via ADO.net den Snapshot Isolation Level nicht verwenden.
Deinem Tipp bezüglich sp_attachdb werde ich noch nachgehen.

Gruss: Martin
Elmar Boye
2006-03-06 23:38:01 UTC
Permalink
Hallo Martin,
Post by Martin Schönholzer
Lustigerweise ist auf meiner besagten SQL-Express Datenbank der
logische Name identisch mit dem Pfad, also: "C:\DOKUMENTE UND
EINSTELLUNGEN\EIGENE DATEIEN\VISUAL STUDIO
2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF"
---------------------------------------------------------
Use "C:\DOKUMENTE UND EINSTELLUNGEN\EIGENE DATEIEN\VISUAL STUDIO
2005\PROJECTS\CSHARPTESTSPACE\CONN2005.MDF"
---------------------------------------------------------
ansprechen kann. (ich tue dies via Management Studio Express)
Hast Du die Datenbank - z. B. eine Tabelle offen?
Dann kann der Wechsel nicht erfolgen.
Post by Martin Schönholzer
diese Abfrage zeigt ja unter anderem für alle Db's den Wert von der
Snapshot aktivierung: (snapshot_isolation_state_desc). Der Wert ist
dort auf ON.
Unten mal ein - ziemlich rudimentärer - Testcode, der auf der Northwind Datenbank
basiert (gibts als Download falls nicht vorhanden) .
Allerdings getestet in einer Developer Edition - aber eine Einschränkung für
Express ist mir nicht bekannt.

Gruss
Elmar

--
///
private void TestSnapshotIsolation()
{
string connectionString = "Data Source=(local)\\SQL2005;Initial Catalog=Northwind;Integrated Security=SSPI;Pooling=true";

// Ändern für (De)Aktivierung
bool ALLOW_SNAPSHOT_ISOLATION = true;
bool READ_COMMITTED_SNAPSHOT = true;

// Verwendete Isolationsstufe für 1./2. Transaktion
IsolationLevel isolationLevel1 = IsolationLevel.Snapshot;
IsolationLevel isolationLevel2 = IsolationLevel.Snapshot;


SqlConnection connection1 = new SqlConnection(connectionString);
SqlCommand command1 = new SqlCommand("", connection1);
command1.CommandTimeout = 5;
SqlConnection connection2 = new SqlConnection(connectionString);
SqlCommand command2 = new SqlCommand("", connection2);
command2.CommandTimeout = 5;

//
// Aktivieren Snapshot Isolation
//
connection1.Open();
try
{
command1.CommandText = string.Format(
"ALTER DATABASE Northwind SET ALLOW_SNAPSHOT_ISOLATION {0}",
(ALLOW_SNAPSHOT_ISOLATION) ? "ON" : "OFF");
command1.ExecuteNonQuery();

command1.CommandText = string.Format(
"ALTER DATABASE Northwind SET READ_COMMITTED_SNAPSHOT {0}",
(READ_COMMITTED_SNAPSHOT) ? "ON" : "OFF");
command1.ExecuteNonQuery();

command1.CommandText = "SELECT snapshot_isolation_state_desc FROM sys.databases WHERE database_id = DB_ID()";
Console.WriteLine("Snapshot Isolation State: {0}", command1.ExecuteScalar());
command1.CommandText = "SELECT is_read_committed_snapshot_on FROM sys.databases WHERE database_id = DB_ID()";
Console.WriteLine("Snapshot Committed State: {0}", command1.ExecuteScalar());
}
finally
{
connection1.Close();
}

//
// Rudimentärer Test mit IsolationLevel.Snapshot
//
connection1.Open();
connection2.Open();

string customersSelect = "SELECT CompanyName FROM Customers WHERE CustomerID = N'ALFKI'";
string customersUpdate = "UPDATE Customers SET CompanyName = UPPER(CompanyName) WHERE CustomerID = N'ALFKI'";

// Wert abrufen fürs Zurücksetzen
command1.CommandText = customersSelect;
string customersReset = string.Format(
"UPDATE Customers SET CompanyName = N'{0}' WHERE CustomerID = N'ALFKI'",
((string)command1.ExecuteScalar()).Replace("'", "''"));

try
{
using (SqlTransaction transaction1 = connection1.BeginTransaction(isolationLevel1))
{
command1.Transaction = transaction1;

using (SqlTransaction transaction2 = connection2.BeginTransaction(isolationLevel2))
{
command2.Transaction = transaction2;

// Lesen und Ändern via Transaktion/Connection 1
command1.CommandText = customersSelect;
Console.WriteLine("Transaction 1 Select CompanyName: {0}", command1.ExecuteScalar());

command1.CommandText = customersUpdate;
command1.ExecuteNonQuery();

command1.CommandText = customersSelect;
Console.WriteLine("Transaction 1 Update CompanyName: {0}", command1.ExecuteScalar());


// Nun lesen und ändern via Transaktion/Connection 2
command2.CommandText = customersSelect;
Console.WriteLine("Transaction 2 Select CompanyName: {0}", command2.ExecuteScalar());

try
{
// schlägt wegen Sperre fehl
command2.CommandText = customersUpdate;
command2.CommandTimeout = 1;
command2.ExecuteNonQuery();
}
catch (SqlException exception2)
{
Console.WriteLine("Transaction 2 Update Fehler: {0}", exception2.Message);
}

// Transaktion 1 und damit Änderungen abschliessen
transaction1.Commit();
Console.WriteLine("Transaction1 committed");


// Nach Commit Transaktion 2 noch einmal
command2.CommandText = customersSelect;
Console.WriteLine("Transaction 2 Select (Commit1) CompanyName: {0}", command2.ExecuteScalar());

// Versuch auf Originalwert zu setzen
try
{
// schlägt wegen vorheriger Änderung fehl
command2.CommandText = customersReset;
command2.CommandTimeout = 1;
command2.ExecuteNonQuery();
}
catch (SqlException exception2)
{
Console.WriteLine("Transaction 2 Update (Commit1) Fehler: {0}", exception2.Message);
}

try
{
// schlägt wegen vorheriger Fehler fehl
transaction2.Commit();
}
catch (SqlException exception2)
{
Console.WriteLine("Transaction 2 SqlException Fehler: {0}", exception2.Message);
}
catch (InvalidOperationException exception2)
{
Console.WriteLine("Transaction 2 InvalidOperation Fehler: {0}", exception2.Message);
}
}
}
}
catch (SqlException exception)
{
Console.WriteLine("General Exception: {0}", exception.Message);
}
finally
{
command1.Transaction = null;
command2.Transaction = null;

connection1.Close();
connection2.Close();
}

connection1.Open();
try
{
command1.CommandText = customersReset;
command1.ExecuteNonQuery();
command1.CommandText = customersSelect;
Console.WriteLine("Reset CompanyName: {0}", command1.ExecuteScalar());
}
catch (SqlException exception)
{
// Tritt auf bei Pooling und Snapshot (BUG?)
Console.WriteLine("General Exception {0}", exception.Message);
}
finally
{
connection1.Close();
}

}
\\\

Loading...