Place of BeginTransaction in code

M

Mukesh

Hi all,
Consider this code

SqlConnection oConn = new
SqlConnection(AccountsConnectionString);
SqlCommand cmdInsert = new SqlCommand("UpdateQuery");
//Location 1:
//SqlTransaction sqlTran = oConn.BeginTransaction();
try
{
oConn.Open();
//Location 2:
//SqlTransaction sqlTran = oConn.BeginTransaction();
cmdInsert.ExecuteNonQuery();
sqlTran.Commit();
}
catch (Exception ex)
{
//Location 3:
sqlTran.Rollback();
}
finally
{
oConn.Close();
}

I have to start a transaction and commit or rollback depending upon the
condition of success of command execution. The problem is if I write
code to Begin Transaction at location 1 it won't work as connection is
still closed. If I write the same at location 2, I won't be able to
rollback transaction at location 3 as sqlTran object is out of
referance. What should I do? I am using framework 2.0.

Thanks and Regards
Chakravarti Mukesh
 
C

Chris Dunaway

SqlConnection oConn = new
SqlConnection(AccountsConnectionString);
SqlCommand cmdInsert = new SqlCommand("UpdateQuery");
//Location 1:
//SqlTransaction sqlTran = oConn.BeginTransaction();
try
{
oConn.Open();
//Location 2:
//SqlTransaction sqlTran = oConn.BeginTransaction();
cmdInsert.ExecuteNonQuery();
sqlTran.Commit();
}
catch (Exception ex)
{
//Location 3:
sqlTran.Rollback();
}
finally
{
oConn.Close();
}

Declare the transaction variable in Location 1, but Begin it in
location 2:

SqlConnection oConn = new
SqlConnection(AccountsConnectionString);
SqlCommand cmdInsert = new SqlCommand("UpdateQuery");
//Location 1:
SqlTransaction sqlTran = null;
try
{
oConn.Open();
//Location 2:
sqlTran = oConn.BeginTransaction();
cmdInsert.ExecuteNonQuery();
sqlTran.Commit();
}
catch (Exception ex)
{
//Location 3:
sqlTran.Rollback();
}
finally
{
oConn.Close();
}
 
M

Marina Levit [MVP]

Declare the transaction object outside the try/catch. Just don't set it to
anything. Then, after you open the connection, inside the try block, set
the variable to the new transaction.

There is no law that says you have to declare the variable and set it to
something in the same line. You can declare everything at the top of your
method, and then use it later. In fact, that is my personal preference,
just to see all the variables involved in my method, so I don't have to
track them down throughout the method.
 
M

Mukesh

Hi,
In fact I tried declaring it on location 1 before posting. But as you
wrote, I was not setting it to anything. Thus I am getting the error
"Object reference not found...". But when I set it to null as Chris
suggested, it is working fine.

Thanks and Regards
Chakravarti Mukesh
 
M

Marina Levit [MVP]

Whether or not you set it to null is irrelevant. When you declare a
variable, it is already null. Setting it to null explitily doesn't change
the value of the variable.

In your exception, you are assuming you have a transaction. If the
connection could not be opened, no transaction would ever have been started.
 
M

Mark Wilden

Whether or not you set it to null is irrelevant. When you declare a
variable, it is already null.

Actually, I don't believe that's true, is it?

///ark
 
M

Marina Levit [MVP]

Yes, it is. A variable that is an object, is initially not pointing to
anything- a.k.a null.

Declare a variable and try to use it without instantiating it - you will
get a NullReferenceException.
Declare the same variable and point it to null and try to use it - you will
get a NullReferenceException.

This applies to objects, not structures.
 
W

Willy Denoyette [MVP]

This is only valid for member variables, local need to be explicitely
assigned/initialized, though failing to do so results in a compiler error .

Willy.

| Yes, it is. A variable that is an object, is initially not pointing to
| anything- a.k.a null.
|
| Declare a variable and try to use it without instantiating it - you will
| get a NullReferenceException.
| Declare the same variable and point it to null and try to use it - you
will
| get a NullReferenceException.
|
| This applies to objects, not structures.
|
| | > | >
| >> Whether or not you set it to null is irrelevant. When you declare a
| >> variable, it is already null.
| >
| > Actually, I don't believe that's true, is it?
| >
| > ///ark
| >
| >
|
|
 
M

Marina Levit [MVP]

Error or warning? I know in VB, it is a warning. And in 2003 I don't
remember C# requiring you to assign values to variables.

Either way, it is a compiler issue. That is a compiler validation - but
effectively assigning a variable to null is the same as not assigning it a
value to begin with.
 
M

Mark Wilden

Error or warning? I know in VB, it is a warning. And in 2003 I don't
remember C# requiring you to assign values to variables.

C# require variables to be "definitely assigned" before use. So an
uninitialized variable could be null or it could be anything else - there's
no way to tell. :)

///ark
 
W

Willy Denoyette [MVP]

In C# it's an error, C# enforces explicit assignment of local variables
before usage.
In VB.NET it results in a warning, but here the compiler implicitely assigns
nothing (null) to the variable of a reference type. Other variable types are
initialized to their default values (which is all 0) but without a compiler
warning!! :-(.

Willy.

| Error or warning? I know in VB, it is a warning. And in 2003 I don't
| remember C# requiring you to assign values to variables.
|
| Either way, it is a compiler issue. That is a compiler validation - but
| effectively assigning a variable to null is the same as not assigning it a
| value to begin with.
|
| | > This is only valid for member variables, local need to be explicitely
| > assigned/initialized, though failing to do so results in a compiler
error
| > .
| >
| > Willy.
| >
| > | > | Yes, it is. A variable that is an object, is initially not pointing
to
| > | anything- a.k.a null.
| > |
| > | Declare a variable and try to use it without instantiating it - you
| > will
| > | get a NullReferenceException.
| > | Declare the same variable and point it to null and try to use it - you
| > will
| > | get a NullReferenceException.
| > |
| > | This applies to objects, not structures.
| > |
| > | | > | > | > | >
| > | >> Whether or not you set it to null is irrelevant. When you declare a
| > | >> variable, it is already null.
| > | >
| > | > Actually, I don't believe that's true, is it?
| > | >
| > | > ///ark
| > | >
| > | >
| > |
| > |
| >
| >
|
|
 
W

Willy Denoyette [MVP]

| |
| > Error or warning? I know in VB, it is a warning. And in 2003 I don't
| > remember C# requiring you to assign values to variables.
|
| C# require variables to be "definitely assigned" before use. So an
| uninitialized variable could be null or it could be anything else -
there's
| no way to tell. :)
|

That's right, if the compiler would accept this without any "behind the back
trickery", the value of the variable would be what's stored in the stack at
the variables location, and that could be anything.

Willy.
 
M

Marina Levit [MVP]

I don't think this would actually be part of the C# language specification.
This is a compiler issue. The compiler could just as easily not give an
error about this - and your code may just crash at run time. Or it could
compile it as if the developer had set the object to 'null' explicitly even
when he/she didn't.

It's really a matter of compiler implementation. The VB compiler chooses
not to be so strict. C# could do the same.
 
M

Marina Levit [MVP]

My whole point was, that this is all actually related to the implementation
of the compiler, and not C# specifications. And that the C# compiler could
just as easily do what the VB compiler does.
 
M

Mark Wilden

I don't think this would actually be part of the C# language specification.

Definite assignment is indeed part of the C# language specification. For a
compiler to be C#-compliant, it is not permitted compile a reference to a
local variable before assignment. Someone no doubt has the reference to
hand, but mine's at home.

///ark
 
M

Mark Wilden

My whole point was, that this is all actually related to the
implementation of the compiler, and not C# specifications.

If you haven't read the C# specification, how can you be so sure?

///ark
 
M

Marina Levit [MVP]

Ok, you are right, I can't be. I guess I don't see why it would have to be
in the specifications, and why the compiler couldn't just take care of it
behind the scenes? I also don't see why MS would decide to add this kind of
inconsistency between C# and VB. And have one compiler take care of things
behind the scenes, and the other force you to assign a value.

I also don't see why assigning a variable to null, somehow now makes it
compile. I mean, the variable is null. Unless you make an assignment, when
you try to call a method or something on it, it will fail. So what if
technically you added a line of code assigning it a value - that value was
null! So why should it be any different then never writing that line of
code assigning the variable to null?
 
M

Mark Wilden

Ok, you are right, I can't be. I guess I don't see why it would have to be
in the specifications, and why the compiler couldn't just take care of it
behind the scenes?

I agree with you. Based on my theory that smart people don't generally do
dumb things, I bet there's a good reason for this (efficiency?), but I don't
know what it is either.

///ark
 
W

Willy Denoyette [MVP]

| Ok, you are right, I can't be. I guess I don't see why it would have to be
| in the specifications, and why the compiler couldn't just take care of it
| behind the scenes? I also don't see why MS would decide to add this kind
of
| inconsistency between C# and VB. And have one compiler take care of things
| behind the scenes, and the other force you to assign a value.
|
The C# language designers learned a lesson from the C language which did not
enforce this explicit assignment. The VB language team took another
approach, while the first version of the compiler did not issue a warning,
they finally concluded that it was important to warn the developer for a
"possibly wrong" default assignment, after which you are forced to assign
explicitly to get rid of the warning. IMO they had better taken the C#
route.


| I also don't see why assigning a variable to null, somehow now makes it
| compile. I mean, the variable is null. Unless you make an assignment, when
| you try to call a method or something on it, it will fail.
But references are also used as method arguments or as a return variable, so
here a method call wouldn't fail, right?.
Anyway, the C# compiler doesn't force you to assign null, he forces you to
think about what value you need to assign, while the VB compiler doesn't
force anything, unless you treat all warnings as errors (a command line and
VS option for the compiler).

Also, this is not about reference types only, also value types must be
'definitely assigned', which is better than the inconsistent VB behavior.


So what if
| technically you added a line of code assigning it a value - that value was
| null! So why should it be any different then never writing that line of
| code assigning the variable to null?
|

But no-one is talking about null assignments onl.


Willy.
 
P

Peter Duniho

Marina Levit said:
[...]
I also don't see why assigning a variable to null, somehow now makes it
compile. I mean, the variable is null. Unless you make an assignment, when
you try to call a method or something on it, it will fail. So what if
technically you added a line of code assigning it a value - that value was
null! So why should it be any different then never writing that line of
code assigning the variable to null?

The point of the assignment is not to make sure it's null at some point, but
rather to ensure that the variable has been assigned to *something* before
you use it.

This is what the C# compiler complains about. It doesn't care whether you
assign it to null or something else. It just cares that you don't try to
use the variable before it's actually been assigned.

IMHO, this is a VERY good thing, as the compiler has no way to know whether
a programmer is implicitly relying on some default behavior, or if they
really just forgot to initialize a variable before using it. The latter is
a common enough bug, and there's very little justification for supporting
implicit behavior.

Now, as it happens the compiler has limited ability to determine whether a
variable has actually been assigned before it's used. IMHO, this is a
problem, as it leads to programmers assigning some random default value like
0 or null, in situations where that's only done just to get the compiler to
shut up when it couldn't figure out that the variable was initialized prior
to use. This means that someone could come along later and add code that
fails to ensure that a useful value has been assigned and does the wrong
thing because of the default assignment the compiler forced on the
programmer, hiding from the compiler that the new code doesn't actually set
the variable to something useful before using it.

But that's a compiler issue, not a language issue. For the language
specification to require all variables to be initialized before use seems
quite reasonable to me. If null happens to be a correct initialization in a
specific case, then that's what you use. If not, you use something more
appropriate. There's nothing magical about using null.

One day (I hope) we'll have a compiler that can correctly detect all
initializations of a variable before that variable's uses, and when that
happens, the world will be perfect. :)

Pete
 

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