IT tutorials
 
Database
 

SQL Server 2008 R2 : Defining Transactions

5/11/2013 2:20:04 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

1. What’s New in Transaction Management

Not much has really changed in SQL Server 2008 related to transactions, transaction logging, and transaction management. About the only real change is the removal of the WITH TRUNCATE_ONLY and WITH NO_LOG options from the BACKUP LOG command. These options are no longer available in SQL Server 2008 to prune the transaction log. The alternative is to switch the database to simple recovery model.

2. What Is a Transaction?

A transaction is one or more SQL statements that must be completed as a whole or, in other words, as a single logical unit of work. Transactions provide a way of collecting and associating multiple actions into a single all-or-nothing multiple-operation action. All operations within the transaction must be fully completed or not performed at all.

Consider a bank transaction in which you move $1,000 from your checking account to your savings account. This transaction is, in fact, two operations: a decrement of your checking account and an increment of your savings account. Consider the impact on your finances if the bank’s server went down after it completed the first step and never got to the second! When the two operations are combined, as a transaction, they either both succeed or both fail as a single, complete unit of work.

A transaction is a logical unit of work that has four special characteristics, known as the ACID properties:

  • Atomicity— Associated modifications are an all-or-nothing proposition; either all are done or none are done.

  • Consistency— After a transaction finishes, all data is in the state it should be in, all internal structures are correct, and everything accurately reflects the transaction that has occurred.

  • Isolation— One transaction cannot interfere with the processes of another transaction.

  • Durability— After the transaction has finished, all changes made are permanent.

The responsibility for enforcing the ACID properties of a transaction is split between T-SQL developers and SQL Server. The developers are responsible for ensuring that the modifications are correctly collected together and that the data is going to be left in a consistent state that corresponds with the actions being taken. SQL Server ensures that the transaction is isolated and durable, undertakes the atomicity requested, and ensures the consistency of the final data structures. The transaction log of each database provides the durability for the transaction.

3. How SQL Server Manages Transactions

SQL Server uses the database’s transaction log to record the modifications that occur within the database. Each log record is labeled with a unique log sequence number (LSN), and all log entries that are part of the same transaction are linked together so that they can be easily located if the transaction needs to be undone or redone. The primary responsibility of logging is to ensure transaction durability—either ensuring that the completed changes make it to the physical database files or ensuring that any unfinished transactions are rolled back in the event of an error or a server failure.

What is logged? Obviously, the start and end of a transaction are logged, but SQL Server also logs the actual data modification, page allocations and de-allocations, and changes to indexes. SQL Server keeps track of a number of pieces of information, all with the aim of ensuring the ACID properties of the transaction.

After a transaction has been committed, it cannot be rolled back. The only way to undo a committed transaction is to write another transaction to reverse the changes made. A transaction can be rolled back before it is committed, however.

SQL Server provides transaction management for all users, using the following components:

  • Transaction-control statements to define the logical units of work

  • A write-ahead transaction log

  • An automatic recovery process

  • Data-locking mechanisms to ensure consistency and transaction isolation


4. Defining Transactions

You can carry out transaction processing with Microsoft SQL Server in three ways:

  • AutoCommit— Every T-SQL statement is its own transaction and automatically commits when it finishes. This is the default mode in which SQL Server operates.

  • Explicit— This approach provides programmatic control of the transaction, using the BEGIN TRAN and COMMIT/ROLLBACK TRAN/WORK commands.

  • Implicit— In this mode, when you issue certain SQL commands, SQL Server automatically starts a transaction. You must finish the transaction by explicitly issuing the COMMIT/ROLLBACK TRAN/WORK commands.

Each of these methods is discussed in the following sections.

Note

The terms for explicit and implicit transactions can be somewhat confusing. The way to keep them straight is to think of how a multistatement transaction is initiated, not how it is completed. AutoCommit transactions are in a separate category because they are both implicitly started and committed.

Implicit and explicit transactions have to be explicitly ended, but explicit transactions must also be explicitly started with the BEGIN TRAN statement, whereas no BEGIN TRAN is necessary to start a multistatement transaction when in implicit transaction mode.


AutoCommit Transactions

AutoCommit is the default transaction mode for SQL Server. Each individual T-SQL command automatically commits or rolls back its work at the end of its execution. Each SQL statement is considered to be its own transaction, with begin and end control points implied. Following is an example:

[implied begin transaction]
UPDATE account
   SET balance = balance + 1000
   WHERE account_no = "123456789"
[implied commit or rollback transaction]

If an error is present in the execution of the statement, the action is undone (that is, rolled back); if no errors occur, the action is completed, and the changes are saved.

Assume that it is written as follows in T-SQL:

declare @checking_account char(10),
        @savings_account char(10)
select @checking_account = '0003456321',
       @savings_account = '0003456322'
update account
   set balance = balance - $1000
   where account_number = @checking_account
update savings_account
   set balance = balance + $1000
   where account_number = @savings_account

What would happen if an error occurred in updating the savings account? With AutoCommit, each statement is implicitly committed after it completes successfully, so the update for the checking account has already been committed. You would have no way of rolling it back except to write another separate update to add the $1,000 back to the account. If the system crashed during the updates, how would you know which updates, if any, completed, and whether you need to undo any of the changes because the subsequent commands were not executed? You would need some way to group the two commands together as a single logical unit of work so they can complete or fail as a whole. SQL Server provides transaction control statements that allow you to explicitly create multistatement user-defined transactions.

Explicit User-Defined Transactions

To have complete control of a transaction and define logical units of work that consist of multiple data modifications, you need to write explicit user-defined transactions. Any SQL Server user can make use of the transaction control statements; no special privileges are required.

To start a multistatement transaction, use the BEGIN TRAN command, which optionally takes a transaction name:

BEGIN TRAN[SACTION] [transaction_name [WITH MARK ['description']]]

The transaction name is essentially meaningless as far as transaction management is concerned, and if transactions are nested , the name is useful only for the outermost BEGIN TRAN statement. Rolling back to any other name, besides a savepoint name (savepoints are covered in the next section), generates an error message similar to the following error message and does not roll back the transaction:

Msg 6401, Level 16, State 1, Line 5
Cannot roll back t2. No transaction or savepoint of that name was found.

Naming transactions is really useful only when you use the WITH MARK option. If the WITH MARK option is specified, a transaction name must be specified. WITH MARK allows for restoring a transaction log backup to a named mark in the transaction log. (For more information on restoring database and log backups. This option allows you to restore a database to a known state or to recover a set of related databases to a consistent state. However, you need to be aware that BEGIN TRAN records are written to the log only if an actual data modification occurs within the transaction.

You complete an explicit transaction by issuing either a COMMIT TRAN or COMMIT [WORK] statement, and you can undo an explicit transaction by using either ROLLBACK TRAN or ROLLBACK [WORK]. The syntax of these commands is as follows:

COMMIT [TRAN[SACTION] [transaction_name]] | [WORK]


ROLLBACK [TRAN[SACTION] [transaction_name | savepointname]] | [WORK]

The COMMIT statement marks the successful conclusion of a transaction. This statement can be coded as COMMIT, COMMIT WORK, or COMMIT TRAN. The only difference is that the first two versions are SQL-92 ANSI compliant.

The ROLLBACK statement unconditionally undoes all work done within the transaction. This statement can also be coded as ROLLBACK, ROLLBACK WORK, or ROLLBACK TRAN. The first two commands are ANSI-92 SQL compliant and do not accept user-defined transaction names. ROLLBACK TRAN is required if you want to roll back to a savepoint within a transaction.

The following example shows how you could code the previously mentioned banking example as a single transaction in SQL Server:

declare @checking_account char(10),
        @savings_account char(10)
select @checking_account = '0003456321',
       @savings_account = '0003456322'
begin tran
update account
   set balance = balance - $1000
   where account_number = @checking_account
if @@error != 0
begin
    rollback tran
    return
end
update savings_account
   set balance = balance + $1000
   where account_number = @savings_account
if @@error != 0
begin
    rollback tran
    return
end
commit tran


					  

Certain commands cannot be specified within a user-defined transaction, primarily because they cannot be effectively rolled back in the event of a failure. In most cases, because of their long-running nature, you would not want them to be specified within a transaction anyway. Following are the commands you cannot specify in a user-defined transaction:

ALTER DATABASE

ALTER FULLTEXT CATALOG

ALTER FULLTEXT INDEX

BACKUP DATABASE

BACKUP LOG

CREATE DATABASE

CREATE FULLTEXT CATALOG

CREATE FULLTEXT INDEX

DROP DATABASE

DROP FULLTEXT CATALOG

DROP FULLTEXT INDEX

RESTORE DATABASE

RECONFIGURE

RESTORE LOG

UPDATE STATISTICS

Savepoints

A savepoint allows you to set a marker in a transaction that you can roll back to undo a portion of the transaction but commit the remainder of the transaction. The syntax is as follows:

SAVE TRAN[SACTION] savepointname

Savepoints are not ANSI-SQL 92 compliant, so you must use the SQL Server–specific transaction management commands that allow you to specify a named point within the transaction and then recover back to it.

The following code illustrates the differences between the two types of syntax when using the SAVE TRAN command:

SQL-92 SyntaxSQL Server–Specific Syntax
BEGIN TRAN mywork
 UPDATE table1...
 SAVE TRAN savepoint1
  INSERT INTO table2...
  DELETE table3...
  IF @@error = -1
     ROLLBACK WORK
COMMIT WORK

BEGIN TRAN mywork
 UPDATE table1...
 SAVE TRAN savepoint1
  INSERT INTO table2...
  DELETE table3...
  IF @@error = -1
     ROLLBACK TRAN savepoint1
COMMIT TRAN


Note the difference between the SQL-92 syntax on the left and the SQL Server–specific syntax on the right. In the SQL-92 syntax, when you reach the ROLLBACK WORK command, the entire transaction is undone rather than undoing only to the point marked by the savepoint. You have to use the SQL Server–specific ROLLBACK TRAN command and specify the savepoint name to roll back the work to the savepoint and still be able to subsequently roll back or commit the rest of the transaction.

Nested Transactions

As a rule, you can’t have more than one active transaction per user session within SQL Server. However, suppose you have a SQL batch that issues a BEGIN TRAN statement and then subsequently invokes a stored procedure, which also issues a BEGIN TRAN statement. Because you can have only one transaction active, what does the BEGIN TRAN inside the stored procedure accomplish? In SQL Server, this leads to an interesting anomaly referred to as nested transactions.

To determine whether transactions are open and how deep they are nested within a connection, you can use the global function @@trancount. If no transaction is active, the transaction nesting level is 0. As a transaction is initiated, the transaction nesting level is incremented; as a transaction completes, the transaction nesting is decremented. The overall transaction remains open and can be entirely rolled back until the transaction nesting level returns to 0.

You can use the @@trancount function to monitor the current status of a transaction. For example, what would SQL Server do when encountering the following transaction (which produces an error because of the reference constraint on the titles table)?

use BIGPUBS2008
go
BEGIN TRAN
   DELETE FROM publishers
   WHERE pub_id = '0736'
go

Msg 547, Level 16, State 0, Line 2
The DELETE statement conflicted with the REFERENCE constraint
 "FK__pub_info__pub_id__2BDE8E15". The conflict occurred in database
 "bigpubs2008", table "dbo.pub_info", column 'pub_id'.
The statement has been terminated.

Is the transaction still active? You can find out by using the @@trancount function:

select @@trancount
go

-----------
          1

In this case, @@trancount returns a value of 1, which indicates that the transaction is still open and in progress. This means that you can still issue commands within the transaction and commit the changes, or you can roll back the transaction. Also, if you were to log out of the user session from SQL Server before the transaction nesting level reached 0, SQL Server would automatically roll back the transaction.

Although nothing prevents you from coding a BEGIN TRAN within another BEGIN TRAN, doing so has no real benefit, even though such cases might occur. However, if you nest transactions in this manner, you must execute a COMMIT statement for each BEGIN TRAN statement issued. The reason is that SQL Server modifies the @@trancount with each transaction statement and considers the transaction finished only when the transaction nesting level returns to 0. Table 1 shows the effects that transaction control statements have on @@trancount.

Table 1. Transaction Statements’ Effects on @@trancount
StatementEffect on @@trancount
BEGIN TRAN+1
COMMIT−1
ROLLBACKSets to 0
SAVE TRAN savepointNo effect
ROLLBACK TRAN savepointNo effect

Following is a summary of how transactional control relates to the values reported by:

  • When you log in to SQL Server, the value of @@trancount for your session is initially 0.

  • Each time you execute begin transaction, SQL Server increments @@trancount.

  • Each time you execute commit transaction, SQL Server decrements @@trancount.

  • Actual work is committed only when @@trancount reaches 0 again.

  • When you execute ROLLBACK TRANSACTION, the transaction is canceled and @@trancount returns to 0. Notice that ROLLBACK TRANSACTION cuts straight through any number of nested transactions, canceling the overall main transaction. This means that you need to be careful how you write code that contains a ROLLBACK statement. You need to be sure to check for the return status up through all levels and exit accordingly so you don’t continue executing data modifications that were meant to be part of the larger overall transaction.

  • Setting savepoints and rolling back to a savepoint do not affect @@trancount or transaction nesting in any way.

  • If a user connection is lost for any reason when @@trancount is greater than 0, any pending work for that connection is automatically rolled back. SQL Server requires that multistatement transactions be explicitly committed.

  • Because the BEGIN TRAN statement increments @@trancount, each BEGIN TRAN statement must be paired with a COMMIT for the transaction to complete successfully.

Let’s look at some sample code to see the values of @@trancount as the transaction progresses. This first example is a simple explicit transaction with a nested BEGIN TRAN:

SQL Statement@@trancount Value
SELECT "Starting....."
BEGIN TRAN
 DELETE FROM table1
 BEGIN TRAN
   INSERT INTO table2
 COMMIT
 UPDATE table3
COMMIT

0
1
1
2
2
1
1
0


Transactions are nested syntactically only. The only commit tran statement that has an impact on real data is the last one, the statement that returns @@trancount to 0. That statement fully commits the work done by the initial and nested transactions. Until that final COMMIT TRAN is encountered, all the work can be rolled back with a ROLLBACK statement.

As a general rule of thumb, if a transaction is already active, you shouldn’t issue another BEGIN TRAN statement. You should check the value of @@trancount to determine whether a transaction is already active. If you want to be able to roll back the work performed within a nested transaction without rolling back the entire transaction, you can set a savepoint instead of issuing a BEGIN TRAN statement. 

Implicit Transactions

AutoCommit transactions and explicit user-defined transactions, which are the default transaction mode in SQL Server 2008, are not ANSI-92 SQL compliant. The ANSI-92 SQL standard states that any data retrieval or modification statement issued should implicitly begin a multistatement transaction that remains in effect until an explicit ROLLBACK or COMMIT statement is issued. Microsoft refers to this transation mode as IMPLICIT_TRANSACTIONS.

To enable implicit transactions for a connection in SQL Server 2008, you need to enable the IMPLICIT_TRANSACTIONS session setting using the following command:

SET IMPLICIT_TRANSACTIONS ON

After this option is turned on, transactions are implicitly started, if they are not already in progress, whenever any of the following commands are executed:

ALTER TABLE

CREATE

DELETE

DROP

FETCH

GRANT

INSERT

OPEN

REVOKE

SELECT

TRUNCATE TABLE

UPDATE

Note that neither the ALTER VIEW nor ALTER PROCEDURE statement starts an implicit transaction.

You must explicitly complete implicit transactions by issuing a COMMIT or ROLLBACK; a new transaction is started again on the execution of any of the preceding commands. If you plan to use implicit transactions, the main issue to be aware of is that locks are held until you explicitly commit the transaction. This can cause problems with concurrency and the system’s capability to truncate the transaction log.

Even when using implicit transactions, you can still issue the BEGIN TRAN statement and create transaction nesting. In the following example, IMPLICIT_TRANSACTIONS ON is turned on to see the effect this has on the value of @@trancount.

SQL Statements@@trancount Value
SET IMPLICIT_TRANSACTIONS ON0
go0
INSERT INTO table11
UPDATE table21
COMMIT0
go 
SELECT * FROM table11
BEGIN TRAN2
DELETE FROM table12
COMMIT1
go 
DROP TABLE table11
COMMIT0

As you can see in this example, if a BEGIN TRAN is issued while a transaction is still active, transaction nesting occurs, and a second COMMIT is required to finish the transaction. The main difference between this example and the preceding one is that here, a BEGIN TRAN is not required to start the transaction. The first INSERT statement initiates the transaction. When you are running in implicit transaction mode, you don’t need to issue a BEGIN TRAN statement; in fact, you should avoid doing so to prevent transaction nesting and the need for multiple commits.

The following example shows the previous banking transaction using implicit transactions:

set implicit_transactions on
go

declare @checking_account char(10),
        @savings_account char(10)
select @checking_account = '0003456321',
       @savings_account = '0003456322'
update account
   set balance = balance - $1000
   where account_number = @checking_account
if @@error != 0
begin
    rollback
    return
end
update savings_account
   set balance = balance + $1000
   where account_number = @savings_account
if @@error != 0
begin
    rollback
    return
end
commit


					  

This example is nearly identical to the explicit transaction example except for the lack of a BEGIN TRAN statement. In addition, when in implicit transaction mode, you cannot roll back to a named transaction because no name is assigned when the transaction is invoked implicitly. You can, however, still set savepoints and roll back to savepoints to partially roll back work within an implicit transaction.

Tip

If you need to know within your SQL code whether implicit transactions are enabled so you can avoid issuing explicit BEGIN TRAN statements, you can check the @@options function. @@options returns a bitmap that indicates which session-level options are enabled for the current session. If bit 2 is on, implicit transactions are enabled. The following code snippet can be used in stored procedures or SQL batches to check this value and decide whether to issue a BEGIN TRAN statement:

if @@options & 2 != 2 — if bit 2 is not turned on
  BEGIN TRAN —a begin tran can be issued since implicit transactions
are off
...


Implicit Transactions Versus Explicit Transactions

When would you want to use implicit transactions versus explicit transactions? If you are porting an application from another database environment, such as DB2 or Oracle, that uses implicit transactions, that application converts over to SQL Server more easily and with fewer code changes if you run in implicit transaction mode. Also, if the application you are developing needs to be ANSI compliant and run across multiple database platforms with minimal code changes, you might want to use implicit transactions.

If you use implicit transactions in your applications, you need to be sure to issue COMMIT statements as frequently as possible to prevent leaving transactions open and holding locks for an extended period of time, which can have an adverse impact on concurrency and overall system performance.

If an application is going to be hosted only on SQL Server, it is recommended that you use AutoCommit and explicit transactions so that changes are committed as quickly as possible and so that only those logical units of work that are explicitly defined contain multiple commands within a transaction.

 
Others
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us