{"id":1647,"date":"2015-12-01T16:30:00","date_gmt":"2015-12-01T14:30:00","guid":{"rendered":"https:\/\/www.sqlinthewild.co.za\/?p=1647"},"modified":"2015-12-17T11:29:18","modified_gmt":"2015-12-17T09:29:18","slug":"why-would-you-want-to-name-a-transaction","status":"publish","type":"post","link":"https:\/\/www.sqlinthewild.co.za\/index.php\/2015\/12\/01\/why-would-you-want-to-name-a-transaction\/","title":{"rendered":"Why would you want to name a transaction?"},"content":{"rendered":"<p>Something that i keep seeing in documentation, in forum code and in real systems is transactions that have names<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">BEGIN TRANSACTION VeryImportantProcess\r\n\r\n&lt;do stuff&gt;\r\n\r\nCOMMIT VeryImportantProcess<\/pre>\n<p>Now the question came up on the forums a while back as to what the point of this is. Why would you name a transaction, what effect does it have on behaviour and how is it treated internally?<\/p>\n<p>In the first post in this series I had a look at nested transactions and in that post we saw that nested transactions don\u2019t have any effect on how the transactions are treated. The BEGIN TRANSACTION statement isn\u2019t even logged if there\u2019s already an open transaction in that session and a ROLLBACK still rolls everything back (unless it\u2019s specifically rolling back to a savepoint)<\/p>\n<p>First question then regarding naming of transactions is whether it has any effect at all on that behaviour.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">CREATE TABLE TestTrans (\r\nID int,\r\nInsertDate DATETIME\r\n);\r\n\r\nBEGIN TRANSACTION OuterTran\r\n  INSERT INTO TestTrans (ID, InsertDate) VALUES (1,GETDATE())\r\n  BEGIN TRANSACTION InnerTran\r\n    INSERT INTO TestTrans (ID, InsertDate) VALUES (2,GETDATE())\r\n  COMMIT TRANSACTION InnerTran\r\nROLLBACK TRANSACTION OuterTran\r\n\r\nSELECT * FROM TestTrans<\/pre>\n<p><a href=\"https:\/\/www.sqlinthewild.co.za\/wp-content\/uploads\/2015\/10\/NoRecords.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; border-width: 0px;\" title=\"NoRecords\" src=\"https:\/\/www.sqlinthewild.co.za\/wp-content\/uploads\/2015\/10\/NoRecords_thumb.png\" alt=\"NoRecords\" width=\"158\" height=\"122\" border=\"0\" \/><\/a><\/p>\n<p>Clearly none. Even with all the transactions named, a commit of a named transaction did not commit anything until the transaction nest level reached 0. A rollback still rolls back everything.<\/p>\n<p>Ok, so maybe there\u2019s some internal usage for a transaction\u2019s name. Let\u2019s have a look at the transaction log to see.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">CHECKPOINT;\r\n\r\nBEGIN TRANSACTION OuterTran\r\n  INSERT INTO TestTrans (ID, InsertDate) VALUES (1,GETDATE())\r\n  BEGIN TRANSACTION InnerTran\r\n    INSERT INTO TestTrans (ID, InsertDate) VALUES (2,GETDATE())\r\n  COMMIT TRANSACTION InnerTran\r\nROLLBACK TRANSACTION OuterTran\r\n\r\nSELECT * FROM fn_DBLog(NULL, NULL)<\/pre>\n<p><a href=\"https:\/\/www.sqlinthewild.co.za\/wp-content\/uploads\/2015\/10\/TranLogContents.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; border-width: 0px;\" title=\"TranLogContents\" src=\"https:\/\/www.sqlinthewild.co.za\/wp-content\/uploads\/2015\/10\/TranLogContents_thumb.png\" alt=\"TranLogContents\" width=\"484\" height=\"118\" border=\"0\" \/><\/a><\/p>\n<p>The outer transaction\u2019s name appears in the log, replacing what was \u2018user_transaction\u2019 previously, but other than that there\u2019s no differences. The inner transaction still doesn\u2019t appear anywhere in the log, neither does the inner commit, and the rollback doesn\u2019t reference the transaction name anywhere.<\/p>\n<p>So what conclusion can we come to here? Pretty much that naming of transactions has one real use, as a form of documentation. Instead of putting a comment above an BEGIN TRANSACTION we can give the transaction a name that indicates what the transaction does, That\u2019s about the only real use.<\/p>\n<p>With two exceptions.<\/p>\n<p>There\u2019s a seldom used option on a BEGIN TRANACTION, an optional WITH clause, Using that along with the transaction name can have some uses in exceptional circumstances.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">BEGIN TRANSACTION VeryImportantProcess WITH MARK\r\n\r\n&lt;do stuff&gt;\r\n\r\nCOMMIT TRANSACTION VeryImportantProcess<\/pre>\n<p>Now if we run an example of that and look into the log, there\u2019s something different there. Interestingly, the difference isn\u2019t on the BEGIN_XACT, it\u2019s on the COMMIT_XACT log record.<\/p>\n<p><a href=\"https:\/\/www.sqlinthewild.co.za\/wp-content\/uploads\/2015\/10\/2015_10_05_15_55_36_SQLQuery1.sql_EXCALIBUR.TransactionDemo_Excalibur_Gail_54_Microsoft_SQL_.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;\" title=\"2015_10_05_15_55_36_SQLQuery1.sql_EXCALIBUR.TransactionDemo_Excalibur_Gail_54_Microsoft_SQL_\" src=\"https:\/\/www.sqlinthewild.co.za\/wp-content\/uploads\/2015\/10\/2015_10_05_15_55_36_SQLQuery1.sql_EXCALIBUR.TransactionDemo_Excalibur_Gail_54_Microsoft_SQL__thu.png\" alt=\"2015_10_05_15_55_36_SQLQuery1.sql_EXCALIBUR.TransactionDemo_Excalibur_Gail_54_Microsoft_SQL_\" width=\"484\" height=\"80\" border=\"0\" \/><\/a><\/p>\n<p>The question still stands though, why do this? Why name a transaction and put a mark of that into the transaction log. What\u00a0 benefit does it give?<\/p>\n<p>The mark can be used with a rather poorly known and seldom used pair of options on the restore command (when restoring transaction log backups)<\/p>\n<ul>\n<li>WITH STOPAFTERMARK<\/li>\n<li>WITH STOPBEFOREMARK<\/li>\n<\/ul>\n<p>These two, similar to the better known STOPAT can be used to stop a transaction log restore part way through a log backup. Unlike STOPAT, they don\u2019t take a time, but rather take a string, a name that was used for a marked transaction name.<\/p>\n<p>Now to be honest there\u2019s not all that much use for this. If a user drops a table or otherwise messes data up requiring a restore to the point before that happened they\u2019re not going to be nice and run that accidental data mess up in a named, marked transaction.<\/p>\n<p>Where it can be useful is when the transaction crossed multiple databases and\/or multiple servers. The log mark appears in all of them and can therefore be used to restore multiple databases to a consistent state where that consistent state is not a single point in time.<\/p>\n<p>Still, it\u2019s useful to have in the toolbox just in case some circumstance comes up where it\u2019s needed.<\/p>\n<p>Edit: It was pointed out, both on twitter and in the comments, that adding a name to a transaction reflects in the transaction-related DMVs and potentially makes debugging easier. Absolutely, it can do and it&#8217;s a valid reason to name transactions, I&#8217;m lumping that in with &#8216;documentation&#8217; in the discussions here.<\/p>\n<p>There\u2019s another case where naming transactions can affect behaviour and in this case usually in a bad way. I\u2019ll look at in in more detail in part 4 of this series, but for now will just reference the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms181299.aspx\">relevant segment<\/a> in Books Online:<\/p>\n<blockquote><p><em>transaction_name<\/em>\u00a0Is the name assigned to the transaction on BEGIN TRANSACTION. <em>transaction_name<\/em> must conform to the rules for identifiers, but only the first 32 characters of the transaction name are used. <strong>When nesting transactions, <em>transaction_name<\/em> must be the name from the outermost BEGIN TRANSACTION statement<\/strong>. <em>transaction_name<\/em> is always case sensitive, even when the instance of SQL Server is not case sensitive.<\/p><\/blockquote>\n<p>The full list is:<\/p>\n<ol>\n<li><a href=\"https:\/\/www.sqlinthewild.co.za\/index.php\/2015\/11\/03\/a-mess-of-nested-transactions\/\">A Mess of Nested Transactions<\/a><\/li>\n<li><a href=\"https:\/\/www.sqlinthewild.co.za\/index.php\/2015\/11\/17\/savepoints-and-conditional-transactions\/\">Savepoints and conditional transactions<\/a><\/li>\n<li>Why would you want to name a transaction? (This post)<\/li>\n<li><a href=\"https:\/\/www.sqlinthewild.co.za\/index.php\/2015\/12\/15\/when-naming-transactions-causes-an-error\/\">When naming transactions causes an error<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Something that i keep seeing in documentation, in forum code and in real systems is transactions that have names BEGIN TRANSACTION VeryImportantProcess &lt;do stuff&gt; COMMIT VeryImportantProcess Now the question came up on the forums a while back as to what&#8230; <a class=\"read-more-button\" href=\"https:\/\/www.sqlinthewild.co.za\/index.php\/2015\/12\/01\/why-would-you-want-to-name-a-transaction\/\">(Read more)<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"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":"Blog post: Why would you want to name a transaction?","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[15,16,17],"tags":[],"class_list":["post-1647","post","type-post","status-publish","format-standard","hentry","category-sql-server","category-syndication","category-t-sql"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p7h6n-qz","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/posts\/1647","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/comments?post=1647"}],"version-history":[{"count":10,"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/posts\/1647\/revisions"}],"predecessor-version":[{"id":1740,"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/posts\/1647\/revisions\/1740"}],"wp:attachment":[{"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/media?parent=1647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/categories?post=1647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlinthewild.co.za\/index.php\/wp-json\/wp\/v2\/tags?post=1647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}