1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Using ADO.NET and SQL Server DBMS Transactions Together doc

5 454 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Using ADO.NET and SQL Server DBMS Transactions Together
Tác giả Team Lib
Thể loại Recipe
Định dạng
Số trang 5
Dung lượng 17,44 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

[ Team LiB ]Recipe 6.4 Using ADO.NET and SQL Server DBMS Transactions Together Problem You need to use a DBMS transaction within a SQL Server stored procedure from an ADO.NET transacti

Trang 1

[ Team LiB ]

Recipe 6.4 Using ADO.NET and SQL Server DBMS Transactions Together

Problem

You need to use a DBMS transaction within a SQL Server stored procedure from an ADO.NET transaction with the SQL Server NET data provider

Solution

Use error-checking within a catch block as shown in Example 6-5

The sample uses a single stored procedure:

InsertCategories_Transacted

Used to insert a single record into the Categories table in the Northwind database within a DBMS transaction If the record insert fails, the transaction is rolled back; otherwise, the transaction is committed

The sample code contains two event handlers:

Form.Load

Sets up the sample by filling a DataTable with the Categories table from the

Northwind sample database The default view of the table is bound to a data grid

on the form

Insert Button.Click

Inserts user-entered data for the Categories records into the Northwind database within a manual transaction using a DBMS transacted stored procedure The transaction is rolled back in the stored procedure if either the Force DBMS

Rollback checkbox is checked or if no value is entered for the Category Name field Otherwise, the ADO.NET manual transaction is committed

Example 6-5 Stored procedure: InsertCategories_Transacted

CREATE PROCEDURE InsertCategories_Transacted

@CategoryId int output,

@CategoryName nvarchar(15),

@Description ntext,

@Rollback bit = 0

Trang 2

AS

SET NOCOUNT ON

begin tran

insert Categories(

CategoryName,

Description)

values (

@CategoryName,

@Description)

if @@error<>0 or @@rowcount=0 or @Rollback=1 begin

rollback tran

set @CategoryID = -1

return 1

end

commit tran

set @CategoryID = Scope_Identity( )

select @CategoryID CategoryId

return 0

The C# code is shown in Example 6-6

Example 6-6 File: DbmsTransactionForm.cs

// Namespaces, variables, and constants

using System;

using System.Configuration;

using System.Windows.Forms;

using System.Data;

using System.Data.SqlClient;

private SqlDataAdapter da;

private DataTable dt;

//

Trang 3

private void DbmsTransactionForm_Load(object sender, System.EventArgs e) {

// Fill the table

String sqlText = "SELECT CategoryID, CategoryName, Description " + "FROM Categories";

da = new SqlDataAdapter(sqlText,

ConfigurationSettings.AppSettings["Sql_ConnectString"]);

dt = new DataTable("Categories");

da.FillSchema(dt, SchemaType.Source);

da.Fill(dt);

// Bind the default view of the table to the grid

dataGrid.DataSource = dt.DefaultView;

}

private void insertButton_Click(object sender, System.EventArgs e)

{

// Create the connection

SqlConnection conn = new SqlConnection(

ConfigurationSettings.AppSettings["Sql_ConnectString"]);

// Create the transaction

conn.Open( );

SqlTransaction tran = conn.BeginTransaction( );

// Create command in the transaction with parameters

SqlCommand cmd =

new SqlCommand("InsertCategories_Transacted", conn, tran);

cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add("@CategoryID", SqlDbType.Int).Direction =

ParameterDirection.Output;

cmd.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15); cmd.Parameters.Add("@Description", SqlDbType.NText);

cmd.Parameters.Add("@Rollback", SqlDbType.Bit);

try

{

// Set the parameters to the user-entered values

// Set the CategoryName to DBNull if not entered

if(categoryNameTextBox.Text.Trim( ).Length == 0)

cmd.Parameters["@CategoryName"].Value = DBNull.Value;

else

cmd.Parameters["@CategoryName"].Value =

categoryNameTextBox.Text;

Trang 4

cmd.Parameters["@Description"].Value = descriptionTextBox.Text; cmd.Parameters["@Rollback"].Value =

forceDbmsRollbackCheckBox.Checked ? 1 : 0;

// Attempt to insert the record

cmd.ExecuteNonQuery( );

// Success Commit the transaction

tran.Commit( );

MessageBox.Show("Transaction committed.");

}

catch (SqlException ex)

{

bool spRollback = false;

foreach (SqlError err in ex.Errors)

{

// Check if transaction rolled back in the

// stored procedure

if(err.Number == 266)

{

MessageBox.Show(ex.Message,

"DBMS transaction rolled back in " +

"stored procedure",

MessageBoxButtons.OK,

MessageBoxIcon.Error);

spRollback = true;

break;

}

}

if (!spRollback)

{

// transaction was not rolled back by the DBMS

// SqlException error Roll back the transaction

tran.Rollback( );

MessageBox.Show(ex.Message);

}

}

catch (Exception ex)

{

// Other Exception Roll back the transaction

tran.Rollback( );

MessageBox.Show(ex.Message);

}

Trang 5

finally

{

conn.Close( );

}

// Refresh the data

da.Fill(dt);

}

Discussion

SQL Server returns error 266 if a stored procedure exits with a transaction count that is not the same as when the stored procedure was entered The count is returned by the function @@TRANCOUNT The error simply sends a message to the client and does not affect execution of the stored procedure It doesn't mean that the DBMS transaction in the stored procedure could not be started, completed, or terminated properly

When calling a stored procedure from a NET manual transaction, the transaction count entering the stored procedure is 1 Using the SQL BEGIN TRAN command in the stored procedure creates a nested transaction, increasing the transaction count to 2 If the stored procedure transaction is subsequently committed with the COMMIT TRAN command, the transaction count is decremented back to 1 Keep in mind commits of inner

transactions don't free resources or make modifications permanent, and don't affect outer transactions If ROLLBACK is called, all inner transactions to the outermost transaction are rolled back and the transaction count is decremented to 0 Error 266 is returned by the rolled back stored procedure since the transaction count entering the stored procedure is 1 while the count when exiting is 0 Attempting to commit or roll back the transaction from .NET after it has been rolled back in the stored procedure will cause an

InvalidOperationException because the transaction has already been rolled back

The solution catches exceptions raised while executing a stored procedure and checks if they correspond to SQL Server error 266, which is the mismatch between the starting and exiting stored procedure transaction count values as a result of the stored procedure rolling back the transaction If the stored procedure has rolled back the transaction, it is not rolled back by the NET code All other errors raised while executing the stored procedure are rolled back by the NET code

[ Team LiB ]

Ngày đăng: 21/01/2014, 11:20

TỪ KHÓA LIÊN QUAN