-2

For some reason, SqlCommand.Transaction is not getting set. The code that sets it is definitely getting called (verified in debugger), but after the property is set, the property is still null.

Here's the code...

cmd.Connection = cmd.Connection ?? Connection;
cmd.Transaction = cmd.Transaction ?? Transaction;
if (cmd.Transaction == null && Transaction != null)
{
    var t = Transaction;
    cmd.Transaction = t;
}

Definition of Transaction...

private SqlTransaction Transaction { get; set; }

I added the if statement in case the problem was the coalesce operator (??), but it doesn't seem to help (didn't expect it to, but grasping at straws now).

I looked at the C# code for SqlCommand.Transaction and there is a path where the field won't get set, but in that scenario, an exception is thrown, not to mention that the condition shouldn't be met anyway (SqlCommand.cs source code).

Any suggestions would be appreciated.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Brian
  • 37,399
  • 24
  • 94
  • 109
  • 1
    The code you have doesn't even make sense. You can never enter the `IF` statement, it's unreachable code. Where are you calling [BeginTransaction()](https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.begintransaction(v=vs.110).aspx)? – Erik Philips Apr 03 '18 at 02:45
  • @ErikPhilips I agree that it isn't logical, but it's happening anyway. Something is causing the property to ignore the set, but I'm not sure what. I did determine that SqlTransaction.Connection is null. According to Visual Studio, this is a readonly property (I tried to set it, it threw an error). I'm still digging to see if I can figure out what is going on. Truly odd behavior. As for BeginTransaction, that is happening elsewhere. There is a lot of code between what I shared and where it is called, so it's not practical to include it here. – Brian Apr 03 '18 at 02:56
  • Did you read the [Remarks of SqlCommand.Transaction](https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.transaction(v=vs.110).aspx)? – Erik Philips Apr 03 '18 at 02:58
  • Also I don't believe you understood my comment. Your `IF` statement can *never be entered* based on the code you have, so just delete it. – Erik Philips Apr 03 '18 at 02:59
  • @ErikPhilips I understood your comment and agree with you that it shouldn't work. However, I have verified that it is being entered, whether either of us thinks it should or not. – Brian Apr 03 '18 at 03:02
  • @ErikPhilips Just saw your other comment, yes, I did read the remarks and also looked at the code (I linked to the source code for SqlCommand). According to the source, it should either throw an exception or be set. – Brian Apr 03 '18 at 03:03
  • A. It doesn't throw an exception on SET, it throws on EXECUTE. B [here are DotNetFiddle Tests, you can **never** enter the IF statement](https://dotnetfiddle.net/6uFFZn). So either you pasted the code incorrectly, or something else is wrong. – Erik Philips Apr 03 '18 at 03:08
  • @mjwills cmd.Connection is null, cmd.Transaction is null, Connection has an instance, Transaction has an instance. – Brian Apr 03 '18 at 03:56

1 Answers1

1

I did determine that SqlTransaction.Connection is null.

That is the problem. You may be setting the cmd.Transaction property OK, but when you read it back out, the SqlCommand will check the cmd.Transaction.Connection property, and if it is null, it sets cmd.Transaction back to null. This might make it seem like you never set it to begin with. Note that it does not raise an exception in this scenario. Here is the relevant source code.

new public SqlTransaction Transaction
{
    get 
    { 
        if ((null != _transaction) && (null == _transaction.Connection))
        { 
            _transaction = null;
        } 
        return _transaction;
    } 
    /* snip */
}
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Should have checked what get was doing :). Now I've got to figure out why SqlTransaction.Connection is getting set to null :(. Thanks! – Brian Apr 03 '18 at 03:57
  • SqlTransaction.Connection was getting set to null because there was a deadlock error. I had some code that would retry a command if there was a deadlock. It checked to see if there was a transaction associated with the command, but, as the question shows, that was coming back as null so that check wasn't working correctly. – Brian Apr 03 '18 at 15:46