In this article, we shall learn how to use transactions in ADO.NET.
ADO.NET is a data access mechanism to communicate with the data sources such as SQL server, XML, ODBC & OLEDB data sources. It allows us to work in connected (database connection is alive while the operation is performed) as well as disconnected architecture (database connection is closed and operation can be performed on the in-memory data).
Get hundreds of ASP.NET Tips and Tricks and ASP.NET Online training here.
In order to guarantee that failing execution of one sql statements in the group of statements, rollbacks the changes made by other successful statements as well, we can use this approach of enforcing the transactions. So with this approach, either all sql statemetns executes successfully or none executes i.e. it makes the database operations "atomic" in turn guarantees the "atomicity".
Below is my ASPX code that contains a simple form.
<h3>ADO.NET Transaction Demo</h3>
<table cellpadding="3" cellspacing="1">
<tr><td>First name: </td><td><asp:TextBox ID="txtFirstName"
runat="server" /> </td></tr>
<tr><td>Last name: </td><td><asp:TextBox ID="txtLastName" runat="server"
<tr><td>Age: </td><td><asp:TextBox ID="txtAge" runat="server" />
<asp:DropDownList ID="dropActive" runat="server">
<asp:ListItem Text="Yes" Value="True" />
<asp:ListItem Text="No" Value="False" />
<tr><td>File name: </td><td><asp:FileUpload ID="FileUpload1"
<tr><td> </td><td><asp:Button ID="btnSubmit" runat="server"
Text="Submit" OnClick="SubmitData" /></td></tr>
<p><asp:Label ID="lblMessage" runat="server" EnableViewState="false" /></p>
In the above code snippet, we have three textboxes, a dropdown and a FileUpload control. We shall try to enter FirstName, LastName, Age and Active details into one table and File related details into another table. We want to make sure that if any one of the operation is failing no changes will be made to the database.
string _connStr =
protected void SubmitData(object sender, EventArgs e)
// get the connection
using (SqlConnection conn = new SqlConnection(_connStr))
// initialte transaction
using (SqlTransaction transaction = conn.BeginTransaction())
//-- Insert personal details into the database
// write the sql statement to execute
string sql = "INSERT INTO PersonalDetail (FirstName, LastName, Age,
Active) VALUES " +
"(@FirstName, @LastName, @Age, @Active)";
// attach the parameter to pass, if no parameter is in the sql no
need to attach
SqlParameter prms = new SqlParameter;
prms = new SqlParameter("@FirstName", SqlDbType.VarChar, 50);
prms.Value = txtFirstName.Text.Trim();
prms = new SqlParameter("@LastName", SqlDbType.VarChar, 50);
prms.Value = txtLastName.Text.Trim();
prms = new SqlParameter("@Age", SqlDbType.Int);
prms.Value = int.Parse(txtAge.Text.Trim());
prms = new SqlParameter("@Active", SqlDbType.Bit);
prms.Value = bool.Parse(dropActive.SelectedValue);
// instantiate the command object to fire
using (SqlCommand cmd = new SqlCommand(sql, conn))
cmd.Transaction = transaction;
//-- now Insert file into the database
string fileName = FileUpload1.PostedFile.FileName;
int fileLength = FileUpload1.PostedFile.ContentLength;
byte imageBytes = new byte[fileLength];
FileUpload1.PostedFile.InputStream.Read(imageBytes, 0, fileLength);
sql = "INSERT INTO Files (FileName, FileContent, Active) VALUES
(@fileName, @fileContent, @Active)";
SqlParameter prms1 = new SqlParameter;
// purposefully created error by writing parameter name as
"@fileName1" instead of "@fileName"
prms1 = new SqlParameter("@fileName1", SqlDbType.VarChar, 50);
prms1.Value = fileName;
prms1 = new SqlParameter("@fileContent", SqlDbType.Image);
prms1.Value = imageBytes;
prms1 = new SqlParameter("@Active", SqlDbType.Bit);
prms1.Value = true; // hard coded value
using (SqlCommand cmd1 = new SqlCommand(sql, conn))
cmd1.Transaction = transaction;
// looks like everything is fine, commit the transaction
lblMessage.Text = "Record inserted successfully !";
catch (Exception ee)
// error occured, rollback the transaction
lblMessage.Text = "Error occured . " + ee.ToString();
On click of the button,
SubmitData server side method fires. Here we have tried to insert Person details into
PersonalDetail database table and File details into
Files database table (This may not be an ideal scenario, however this will demonstate how both
SqlCommand objects doesn’t affect the database tables if any one of them error out).
SubmitData method, we have first instantiated the
SqlConnection object by passing the connection string; then opened the connection. Once the connection is open, we can call the begin transaction on the connection object (The connection must be in open state before attaching a transaction with it).
Now we have wrapped remaining code under try block so if any error occurs we will be able to call the
transaction.Rollback() method so that all the operations on this connection will be rolled back. In the try block we have executed two Sql statements separately. While executing the second Sql statement, we have purposefully passed wrong parameter as “@firstName1” instead of “@firstName”. Then at the last of the try block we have called the
Commit method of the transaction object that commits the transaction if everything executes well under the try block.
When this code executes, we shall notice that execution of the second command object throws error (due to wrong parameter name) and execution flow goes into the catch block that calls the
Rollabck method of the transaction and the changes made by the first
SqlCommand object gets rolled back (as a result no changes is made in the database even if first SqlCommand object executed successfully).
Above image is my output of the page that clearly shows the error occurred on the page.
Hope you liked this article. Hope you have followed my earlier article on ADO.NET where I have described many frequently used scenarios.
Stay tuned for many more articles like this.