0

I'm writing a c# program and using SQL Server as a database.

I'm running an INSERT, SELECT, and UPDATE followed by each other. The first two statements run okay but the last one, the UPDATE statement, will run once but when it runs the second time it will freeze the program and after 30 seconds or so I get this error:

System.Data.SqlClient.SqlException: 'Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
The statement has been terminated.
Inner Exception
Win32Exception: The wait operation timed out

this is my connection string:

private const string constr = @"Data Source=MSI\SQLEXPRESS;Initial Catalog=DatabaseHuskyCenter;Integrated Security=True ;MultipleActiveResultSets=True";

and this is the table of Inventory:

USE [DatabaseHuskyCenter]
GO

/****** Object:  Table [dbo].[Inventory]    Script Date: 12/21/2020 20:07:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Inventory](
    [IDinventory] [nvarchar](50) NOT NULL,
    [IDitem] [nvarchar](50) NULL,
    [quantity] [int] NULL,
 CONSTRAINT [PK_Inventory] PRIMARY KEY CLUSTERED 
(
    [IDinventory] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Inventory]  WITH CHECK ADD  CONSTRAINT [FK_Inventory_Items] FOREIGN KEY([IDitem])
REFERENCES [dbo].[Items] ([IDitem])
GO

ALTER TABLE [dbo].[Inventory] CHECK CONSTRAINT [FK_Inventory_Items]
GO

This is my application code that runs the three queries:

int quan = 1;
            int m=0;
            string tag = ((PictureBox)sender).Tag.ToString();
            sqlcon = new Connection();
            sqlcon.cmd = new SqlCommand("select * from Inventory,Items where Inventory.IDitem = Items.IDitem and Items.IDitem like '" + tag + "'", sqlcon.con);
            sqlcon.dr = sqlcon.cmd.ExecuteReader();
            sqlcon.dr.Read();
            if (sqlcon.dr.HasRows)
            {
                sqlcon.cmd = new SqlCommand("INSERT INTO SellActions(ID,IDsell,IDitem,IDuser,buyerName,[Date],quantityyy,[index])values(@id,@idsell,@iditem,@iduser,@buyer,@date,@quan,@index)", sqlcon.con);
                sqlcon.cmd.Parameters.AddWithValue("@id", sqlcon.SellActionCode());
                sqlcon.cmd.Parameters.AddWithValue("@idsell",codeTxt.Text);
                sqlcon.cmd.Parameters.AddWithValue("@iditem", tag);
                sqlcon.cmd.Parameters.AddWithValue("@iduser", sqlcon.getUserID());
                sqlcon.cmd.Parameters.AddWithValue("@buyer", nameTxt.Text);
                sqlcon.cmd.Parameters.AddWithValue("@date", dateandtime.Dateshort());
                sqlcon.cmd.Parameters.AddWithValue("@quan", quan);
                sqlcon.cmd.Parameters.AddWithValue("@index", index++); 
                try
                {
                    sqlcon.cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK);
                    throw;
                }
                sqlcon.cmd.Dispose();

                SqlCommand find = new SqlCommand("select quantity from Inventory where IDitem = '" + tag+ "'", sqlcon.con);
                try
                {
                    sqlcon.dr = find.ExecuteReader();
                    while (sqlcon.dr.Read())
                    {
                        m =sqlcon.dr.GetInt32(0);
                    }
                    sqlcon.dr.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw;
                }
                find.Dispose();
                sqlcon.dr.Close();
                m -= quan;
                MessageBox.Show(m.ToString());
                if (sqlcon.con.State == ConnectionState.Closed)
                {
                    sqlcon.con.Open();
                }
                sqlcon.cmd = new SqlCommand("update Inventory set quantity=@quantity where IDitem = @tag", sqlcon.con);
                sqlcon.cmd.Parameters.AddWithValue("@tag", tag.ToString());
                sqlcon.cmd.Parameters.AddWithValue("@quantity", m.ToString());

                try
                {
                    sqlcon.cmd.ExecuteNonQuery();
                    sqlcon.cmd.Dispose();
                    sqlcon.con.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK);
                    throw;
                }
                Clear();
                getData();
            }
            sqlcon.dr.Close();
            ItemLimit++;

its quite a mess, sorry about that but the problem occurs here

if (sqlcon.con.State == ConnectionState.Closed)
                {
                    sqlcon.con.Open();
                }
                sqlcon.cmd = new SqlCommand("update Inventory set quantity=@quantity where IDitem = @tag", sqlcon.con);
                sqlcon.cmd.Parameters.AddWithValue("@tag", tag.ToString());
                sqlcon.cmd.Parameters.AddWithValue("@quantity", m.ToString());

                try
                {
                    sqlcon.cmd.ExecuteNonQuery();
                    sqlcon.cmd.Dispose();
                    sqlcon.con.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK);
                    throw;
                }

And this is an image of the error:

The error

  • 1
    Don't post images of error, paste the text into the question. Also, [can we stop using AddWithValue() already?](https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/) You should be using instead `Parameters.Add`; [AddWithValue is evil](https://www.dbdelta.com/addwithvalue-is-evil/) – Thom A Dec 21 '20 at 14:29
  • @Larnu thanks for your comment, well I, and I never knew about 'parameters.add' – Arevan Shamal Dec 21 '20 at 14:32
  • Evolve - no one should be using [old-style joins](https://sqlblog.org/2009/10/08/bad-habits-to-kick-using-old-style-joins). You also need to parameterize that first statement - concatenating strings into a query is a security risk. – SMor Dec 21 '20 at 14:36
  • I don't think you're working on the data as you'd expect - unless I missed it, I don't see the `conn` opened (and if it's not throwing an error, it _may_ be a connection left hanging somewhere). Refer to [this pattern](https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection?view=dotnet-plat-ext-5.0&viewFallbackFrom=net-5.0)..Hth... – EdSF Dec 21 '20 at 14:37
  • @EdSF, I use a constructor in a class that will open the con automatically and I tried everything that related to con open and close and that wasn't the problem because it will run fine the first time but the second time it will time out. – Arevan Shamal Dec 21 '20 at 14:43
  • You _created_ another one: `sqlcon = new Connection();` – EdSF Dec 21 '20 at 15:00
  • Try add more time to connection string "Connect Timeout=640", but this way is bad. Check you database table about indexes and keys. – Mihal By Dec 21 '20 at 16:14
  • @MihalBy I tried that it keeps giving me errors, that something is wrong about my connection string, but I don't think that's is the case because I'm 'UPDATE' one record. isn't a heavy task from what I know – Arevan Shamal Dec 21 '20 at 16:20
  • If you execute Update script from sql editor(eq microsoft sql server management studio or other) it work fine? – Mihal By Dec 21 '20 at 16:59
  • If it possible add to question masked connection string and DDL of Inventory. – Mihal By Dec 21 '20 at 17:03
  • @MihalBy yes it works fine without a problem but the problem that I cant understand it why it will run the first time I call that function but when I try to run it again I will freeze the program but I have 7 tabs and every tab have flow panel's and everyone works fine except this one and they are the same. – Arevan Shamal Dec 21 '20 at 17:04
  • @MihalBy i added those that u ask – Arevan Shamal Dec 21 '20 at 17:11
  • Meybe, during you update works other process block Inventory table, pls check it. – Mihal By Dec 21 '20 at 17:11
  • My final thing) Try disable MARS in you connection - MultipleActiveResultSets=false – Mihal By Dec 21 '20 at 17:30
  • Execution Timeout Expired is not related to the Connect Timeout set from connection strings. Take a look at the CommandTimeout property on the [SqlCommand](https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.commandtimeout) object. You really need to look into why the update statement is so slow, though... e.g.: does `Inventory.IDItem` have an index on it? – AlwaysLearning Dec 21 '20 at 23:34
  • @AlwaysLearning , I think I found the problem it was with this one " MultipleActiveResultSets=false" but without this, I get many other problems with I have to solve them, but it is a bad thing to use " MultipleActiveResultSets=true " in the connection string – Arevan Shamal Dec 22 '20 at 15:44
  • @MihalBy with your suggestion, I fixed my problem by turning of MultipleActiveResultSets=false thank you :) – Arevan Shamal Dec 23 '20 at 09:52

0 Answers0