{"id":590,"date":"2012-03-23T09:51:38","date_gmt":"2012-03-23T08:51:38","guid":{"rendered":"http:\/\/www.capri-soft.de\/blog\/?p=590"},"modified":"2012-03-23T09:51:38","modified_gmt":"2012-03-23T08:51:38","slug":"c-net-und-sql-server-transaktionen-verwenden","status":"publish","type":"post","link":"https:\/\/www.capri-soft.de\/blog\/?p=590","title":{"rendered":"C#.NET und SQL Server: Transaktionen verwenden"},"content":{"rendered":"<h1>Aufgabenstellung<\/h1>\n<p>Mehrere SQL Statements sollen atomar (ACID) ausgef\u00fchrt werden.<\/p>\n<p>Beispiel:<br \/>\nEin Datenimport mit mehreren INSERT Statements und vorherigen DELETE auf eine existierende Tabelle: W\u00e4hrend ein anderer Benutzer auf die Tabelle zugreift, sieht er nur die Daten die bereits importiert wurden. Dies kann \u00fcber eine Transaktion atomar (wie das umlegen eines Schalters mit COMMIT) ausgef\u00fchrt werden.<\/p>\n<p>Manipulationen (z.B. auf ein Konto) mit mehreren Zugriffen unterschiedlicher User (konkurrierende Zugriffe) k\u00f6nnen zu falschen Betr\u00e4gen auf dem Konto f\u00fchren (Nebenl\u00e4ufigkeitsprobleme):<br \/>\nBei mehreren SQL Kommandos, die sequenziell\/hintereinander ausgef\u00fchrt werden, soll sichergestellt werden das andere Benutzer keine Werte manipulieren, die zu einer falschen Weiterberechnung f\u00fchren (siehe auch: Lost update und Dirty Read bei Datenbanken). <\/p>\n<h1>Vorgehensweise<\/h1>\n<p>Es existiert eine Klasse SqlTransaction, deren Instanz \u00fcber die FactoryMethode .BeginTransaction(&#8222;SampleTransaction&#8220;); zugewiesen werden kann. Die Instanz kann anschlie\u00dfend einem Command zugwiesen werden, welches bis zum COMMIT (Schalter umlegen\/alles \u00fcbernehmen)  Befehle an den SQL Server sendet.<\/p>\n<h1>L\u00f6sung<\/h1>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nprivate static void ExecuteSqlTransaction(string connectionString)\r\n{\r\n    using (SqlConnection connection = new SqlConnection(connectionString))\r\n    {\r\n        connection.Open();\r\n\r\n        SqlCommand command = connection.CreateCommand();\r\n        SqlTransaction transaction;\r\n\r\n        \/\/ Start a local transaction.\r\n        transaction = connection.BeginTransaction(&quot;SampleTransaction&quot;);\r\n\r\n        \/\/ Must assign both transaction object and connection\r\n        \/\/ to Command object for a pending local transaction\r\n        command.Connection = connection;\r\n        command.Transaction = transaction;\r\n\r\n        try\r\n        {\r\n            command.CommandText =\r\n                &quot;Insert into Region (RegionID, RegionDescription) &quot;+\r\n                &quot;VALUES (100, &#039;Description&#039;)&quot;;\r\n            command.ExecuteNonQuery();\r\n            command.CommandText =\r\n                &quot;Insert into Region (RegionID, RegionDescription) &quot;+\r\n                 &quot;VALUES (101, &#039;Description&#039;)&quot;;\r\n            command.ExecuteNonQuery();\r\n\r\n            \/\/ Attempt to commit the transaction.\r\n            transaction.Commit();\r\n            Console.WriteLine(&quot;Both records are written to database.&quot;);\r\n        }\r\n        catch (Exception ex)\r\n        {\r\n            Console.WriteLine(&quot;Commit Exception Type: {0}&quot;, ex.GetType());\r\n            Console.WriteLine(&quot;  Message: {0}&quot;, ex.Message);\r\n\r\n            \/\/ Attempt to roll back the transaction.\r\n            try\r\n            {\r\n                transaction.Rollback();\r\n            }\r\n            catch (Exception ex2)\r\n            {\r\n                \/\/ This catch block will handle any errors that may have occurred\r\n                \/\/ on the server that would cause the rollback to fail, such as\r\n                \/\/ a closed connection.\r\n                Console.WriteLine(&quot;Rollback Exception Type: {0}&quot;, ex2.GetType());\r\n                Console.WriteLine(&quot;  Message: {0}&quot;, ex2.Message);\r\n            }\r\n        }\r\n    }\r\n<\/pre>\n<iframe src=\"http:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Fwww.capri-soft.de%2Fblog%2F%3Fp%3D590&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" style=\"border:none; overflow:hidden; width:450px;margin-top:5px;\"><\/iframe>","protected":false},"excerpt":{"rendered":"<p>Aufgabenstellung Mehrere SQL Statements sollen atomar (ACID) ausgef\u00fchrt werden. Beispiel: Ein Datenimport mit mehreren INSERT Statements und vorherigen DELETE auf eine existierende Tabelle: W\u00e4hrend ein anderer Benutzer auf die Tabelle zugreift, sieht er nur die Daten die bereits importiert wurden. Dies kann \u00fcber eine Transaktion atomar (wie das umlegen eines Schalters mit COMMIT) ausgef\u00fchrt werden. &hellip; <a href=\"https:\/\/www.capri-soft.de\/blog\/?p=590\" class=\"more-link\"><span class=\"screen-reader-text\">C#.NET und SQL Server: Transaktionen verwenden<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4],"tags":[],"class_list":["post-590","post","type-post","status-publish","format-standard","hentry","category-net"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4yGeN-9w","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/590","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=590"}],"version-history":[{"count":4,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/590\/revisions"}],"predecessor-version":[{"id":594,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/590\/revisions\/594"}],"wp:attachment":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=590"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=590"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=590"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}