<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Kalen Delaney : internals, Transactions</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/tags/internals/Transactions/default.aspx</link><description>Tags: internals, Transactions</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>TSQL Tuesday #11:Rolling Back TRUNCATE TABLE</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2010/10/12/tsql-tuesday-11-rolling-back-truncate-table.aspx</link><pubDate>Tue, 12 Oct 2010 20:02:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:29343</guid><dc:creator>Kalen Delaney</dc:creator><slash:comments>9</slash:comments><comments>http://sqlblog.com/blogs/kalen_delaney/comments/29343.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/kalen_delaney/commentrss.aspx?PostID=29343</wfw:commentRss><description>“It ain't what people don't know that hurts them it's what they know that ain't so” -- commonly attributed to Mark Twain SQL Server has been around for a long time now, and people who learn one version well sometimes have monumental task when a new version...(&lt;a href="http://sqlblog.com/blogs/kalen_delaney/archive/2010/10/12/tsql-tuesday-11-rolling-back-truncate-table.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=29343" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/internals/default.aspx">internals</category><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/locking/default.aspx">locking</category><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/Transactions/default.aspx">Transactions</category><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/T-SQL+Tuesday/default.aspx">T-SQL Tuesday</category></item><item><title>Geek City: How SQL Server Detects the Correct Versioned Rows</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2008/04/03/how-sql-server-detects-the-correct-versioned-rows.aspx</link><pubDate>Thu, 03 Apr 2008 19:16:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6033</guid><dc:creator>Kalen Delaney</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/kalen_delaney/comments/6033.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/kalen_delaney/commentrss.aspx?PostID=6033</wfw:commentRss><description>&lt;P&gt;Here is a question I just received from the feedback page on my web site: 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;I have finished the book &amp;lt;the storage engine&amp;gt; and like it very much. I am now reading &amp;lt;query tuning and optimization&amp;gt; &lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;I know in the READ COMMITTED SNAPSHOT isolation, when a row is being modified in a transaction, it generates an old committed version so another transaction can read it without being blocked. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;But I don’t know how SQL Server uses SNAPSHOT isolation to prevent Phantom Read being happening. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;In SERIALIZABLE isolation the ranged key or the whole table is locked, but in SNAPSHOT isolation, it can NOT generate any committed version since the row does NOT exist at the moment. So how does it know that the newly inserted data should not be included in the second SELECT statement?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;-Tom&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Tom is correct in that INSERTS do not generate versioned rows. However, SQL Server is able to keep track of when each change was made under snapshot isolation. Once a database is enabled for snapshots, every rows inserted, deleted or modified gets an additional 14 bytes of overhead added to it. These bytes contain 2 pieces of information. First is a row pointer to the previous committed version of the row, which is stored in the version store in tempdb. This pointer is only used for deleted and updated rows, since there will be no previous values for newly inserted rows. &lt;/P&gt;
&lt;P&gt;However, these extra bytes also include a value called XSN, or transaction sequence number, which you can think of like a timestamp for a database. Any database enabled for snapshot keeps an internal XSN value, that is incremented each time any change is made, or any snapshot select is performed. The metadata also keeps track of all active transactions, and what the XSN was when the transaction started. It uses the view &lt;EM&gt;sys.dm_tran_active_snapshot_database_transactions&lt;/EM&gt; for this.&amp;nbsp; So when you are reading data, SQL Server will look at the XSN number in each row, and not return any rows that have an XSN value greater than the XSN value at the time the transaction started.&lt;/P&gt;
&lt;P&gt;I hope this helps!&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#ff00ff size=5&gt;~Kalen&lt;/FONT&gt; 
&lt;P&gt;&lt;A href="http://www.insidesqlserver.com/"&gt;www.InsideSQLServer.com&lt;/A&gt;&lt;BR&gt;&lt;A href="http://www.sqlserverdvd.com/"&gt;www.SQLServerDVD.com&lt;/A&gt;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6033" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/Inside+SQL+Server/default.aspx">Inside SQL Server</category><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/internals/default.aspx">internals</category><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/snapshot+isolation/default.aspx">snapshot isolation</category><category domain="http://sqlblog.com/blogs/kalen_delaney/archive/tags/Transactions/default.aspx">Transactions</category></item></channel></rss>