Commit/Rollback Transaction generates an error.

G

Guest

I have table

Employee - Code varchar(5)
Name varchar(100)
Age int


Using Ado.Net
1) Create a SQLConnection Object and open the connection.
2) Create a SQLCommand object using that connection.
3) Create a Transaction using
SQLConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted)
4) Attach the Transaction to the SQLCommand (ie. SQLCommand.Transaction=
TransactionObject)
5) Execute an insert statement on the Employee Table using
SQLCommand.ExecuteNonQuery()
(ie. SQLCommand.CommandText = "Insert into Employee(Code, Name, Age)
Values('ABC', 'ABCDEFG', '213')"
SQLCommand.ExecuteNonQuery() )
6) Call another function (eg: test()), which again inserts a record in the
same table.
This function would raise an sql exception, but we would ignore it in the
function.

(ie. Private Sub Test(ByRef oCmd As SqlCommand)
Try
oCmd.CommandText = "Insert into Employee(Code, Name, Age)
Values('XYZ', 'XYZDEFG', '213a')"
'This would raise an error since Age is of Type Int
oCmd.ExecuteNonQuery()
Catch ex As Exception
'Ignore the error and return
MsgBox(ex.Message)
End Try
End Sub )

7) Issue Commit Statement (ie. TransactionObject.Commit())
This statement raises an error "The COMMIT TRANSACTION request has no
corresponding BEGIN TRANSACTION."


Source Code :
-----------------

Imports System.Data.SqlClient

Public Class Form1
Inherits System.Windows.Forms.Form

Private oConn As SqlConnection
Private oCmd As SqlCommand
Private oTran As SqlTransaction


#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents txtName As System.Windows.Forms.TextBox
Friend WithEvents txtAge As System.Windows.Forms.TextBox
Friend WithEvents txtCode As System.Windows.Forms.TextBox
Friend WithEvents Label3 As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.txtName = New System.Windows.Forms.TextBox
Me.txtAge = New System.Windows.Forms.TextBox
Me.Label1 = New System.Windows.Forms.Label
Me.Label2 = New System.Windows.Forms.Label
Me.Button1 = New System.Windows.Forms.Button
Me.txtCode = New System.Windows.Forms.TextBox
Me.Label3 = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'txtName
'
Me.txtName.Location = New System.Drawing.Point(112, 40)
Me.txtName.Name = "txtName"
Me.txtName.Size = New System.Drawing.Size(128, 20)
Me.txtName.TabIndex = 0
Me.txtName.Text = "Edward Fernandes"
'
'txtAge
'
Me.txtAge.Location = New System.Drawing.Point(112, 80)
Me.txtAge.Name = "txtAge"
Me.txtAge.Size = New System.Drawing.Size(128, 20)
Me.txtAge.TabIndex = 1
Me.txtAge.Text = "123"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(16, 40)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(80, 24)
Me.Label1.TabIndex = 3
Me.Label1.Text = "Name"
'
'Label2
'
Me.Label2.Location = New System.Drawing.Point(16, 80)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(80, 24)
Me.Label2.TabIndex = 4
Me.Label2.Text = "Age"
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(40, 136)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(144, 23)
Me.Button1.TabIndex = 5
Me.Button1.Text = "Add to DB"
'
'txtCode
'
Me.txtCode.Location = New System.Drawing.Point(112, 8)
Me.txtCode.Name = "txtCode"
Me.txtCode.Size = New System.Drawing.Size(128, 20)
Me.txtCode.TabIndex = 6
Me.txtCode.Text = "E1111"
'
'Label3
'
Me.Label3.Location = New System.Drawing.Point(16, 8)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(80, 16)
Me.Label3.TabIndex = 7
Me.Label3.Text = "Code"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 272)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.txtCode)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.txtAge)
Me.Controls.Add(Me.txtName)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region


'Employee Table Defintion :
'Code varchar(5)
'Name varchar(100)
'Age int


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
oConn = New SqlConnection("Server=Localhost;user
id=sa;password=sa;Initial Catalog=Northwind")
oConn.Open()
Try
oTran = oConn.BeginTransaction(IsolationLevel.ReadCommitted)
oCmd = New SqlCommand("", oConn)
oCmd.CommandText = "Insert into Employee(Code, Name, Age)
Values('" & txtCode.Text & "','" & txtName.Text & "','" & txtAge.Text & "')"
oCmd.Transaction = oTran
oCmd.ExecuteNonQuery()
Call Test(oCmd) 'Call this method which generates an exception,
which is ignored.
oTran.Commit() 'This will raise an error "The COMMIT TRANSACTION
request has no corresponding BEGIN TRANSACTION."
Catch ex As Exception
MsgBox(ex.Message)
Try
oTran.Rollback() 'This will raise an error "This
SqlTransaction has completed; it is no longer usable."
Catch ex1 As Exception
MsgBox(ex1.Message)
End Try
Finally
oConn.Close()
End Try
End Sub

Private Sub Test(ByRef oCmd As SqlCommand)
Try
oCmd.CommandText = "Insert into Employee(Code, Name, Age)
Values('ABC', 'ABCDEFG', '213a')"
'This would raise an error since Age is of Type Int
oCmd.ExecuteNonQuery()
Catch ex As Exception
'Ignore the error and continue
MsgBox(ex.Message)
End Try
End Sub
End Class
 
R

Robbe Morris [C# MVP]

I have never done it quite that way. I have always passed around the
connection and transaction
object byref and attached them in the SqlCommand constructor in various
methods (I use recursion
a lot to insert all sorts of nested data). I have had no problems in the
parent method rolling back
or committing data based on success or failure in the whole slew of
recursive methods it calls.



--
2005 Microsoft MVP C#
Robbe Morris
http://www.robbemorris.com
http://www.masterado.net/home/listings.aspx
 
G

Guest

I am also passing the SQLCommand byref in the function.
The only difference is, I want to ignore the error if any that occured in
that function (ie. Test()). Also the problem occurs only if the SQL Error is
because of type mismatch.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top