SqlConnection和SqlCommand超时

时间:2017-10-16 05:56:46

标签: c# .net sql-server timeout

对于应该在一组SQL Server数据上运行的代码片段存在一些问题。这个想法是它读入调整大小的jpeg文件并将其写回。它在单行上运行良好。但是,当在大量数据集上运行后续行时,update命令会因超时而失败。不是在所有行上,但它确实跳过大多数行。

using System.Drawing.Imaging;
using System.IO;

namespace MesResizer
{
    class Program
    {
        static void Main(string[] args)
        {
            var con = ConfigurationManager.ConnectionStrings["SQLconnString"].ToString();
            SqlConnection myConnection = new SqlConnection(con);
            GetRows(myConnection);
            myConnection.Close();
        }

        private static void GetRows(SqlConnection connection)
        {
            Boolean changed = false;

            using (connection)
            {
                SqlCommand command = new SqlCommand("SELECT TOP(16000) strIIImage, intIIID FROM InspectionItem;", connection);

                try
                {
                    Writeout("Setting up Database connection..");
                    connection.Open();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.ReadLine();
                    return;
                }

                Writeout("DONE");
                SqlDataReader reader = command.ExecuteReader();

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            int RowId = (int)reader.GetValue(reader.GetOrdinal("intIIID"));
                            Stream str;
                            changed = false;

                            try
                            {
                                str = reader.GetStream(reader.GetOrdinal("strIIImage"));

                                Image imgstr = Image.FromStream(str);
                                imgstr.Save("before.jpg", ImageFormat.Jpeg);

                                if (str.Length > 0)
                                    changed = ScaleImage(Image.FromStream(str), ms);
                            }
                            catch (ArgumentException e)
                            {
                                Writeout("Stream does not have a valid image format or is Null... Unable to process image... " + RowId);
                                Writeout("Exception: " + e.Message);
                            }

                            if (changed)
                                WriteImage(ms, RowId);
                            else
                                Writeout("Image already resized: " + RowId);
                        }
                    }
                }
                else
                {
                    Writeout("No rows found.");
                    Console.ReadLine();
                }

                reader.Close();
                Console.ReadLine();
            }
        }

        private static void WriteImage(MemoryStream ms, int RowId)
        {
            var conf = ConfigurationManager.ConnectionStrings["SQLconnString"].ToString();
            SqlConnection writecon = new SqlConnection(conf);

            writecon.Open();

            using (FileStream file = new FileStream("after.jpg", FileMode.Create, System.IO.FileAccess.Write))
            {
                file.Write(ms.ToArray(), 0, (int)ms.Length);
            }

            using (SqlCommand cmd = new SqlCommand("UPDATE InspectionItem SET strIIImage = @Image WHERE intIIID = @Id", writecon))
            {
                cmd.Parameters.Add("@Image", SqlDbType.VarBinary, (int)ms.Length).Value = ms.ToArray();
                cmd.Parameters.Add("@Id", SqlDbType.Int).Value = RowId;
                cmd.CommandTimeout = 5;

                try
                { //This is where it breaks. :)
                    cmd.ExecuteNonQuery();
                }
                catch (SqlException e)
                {
                    Writeout(e.Message + "Error occured on row: " + RowId);
                    return;
                }
            }

            Writeout("Succesfully Resized File: " + RowId);
            writecon.Close();
        }
    }
}

这里有一些额外的东西,因为我一直在尝试验证存储的图像实际上是否正在调整大小以及其他一些事情,例如具有问题的特定行。

我已经评论了超时发生的代码。 :)

任何信息或方向将不胜感激。

TIA。

修改的 在测试数据库上运行多种图像格式和5000+行,并且完全没有问题。 我可以看到数据是图片的数据,因为我正在将每个数据写入磁盘,但它似乎并不想一直写回数据库。很奇怪

修改的 只是想让任何人想知道对此的解决方案。

结束了SQLdatareader锁定数据库中的行。

我现在正在从数据库中选择行块,将它们移动到关闭datareader的数据表中,并在必要时调整大小并写回。我相信关键是关闭SqlDatareader并释放任何锁。

1 个答案:

答案 0 :(得分:0)

<强>编辑:

我刚刚在您的更新通话中注意到您已设置cmd.CommandTimeout = 5;。这是一个非常短暂的超时,仅需5秒。默认值为30秒,您可能需要花费很多时间来传输文件。

下面的帖子:

这里可能会发生一些事情。由于您正在使用阅读器并逐行进行,因此您可以保持初始连接处于打开状态,但它最终可能会超时。

至于你的其他连接问题,如果你因为达到最大连接数而得到timeout while getting a connection from pool例外而不是传统的超时,我不会感到惊讶。当你处于一个紧密的循环内并不断打开/关闭连接时。

我还会在你的更新内部包含你的更新连接,由于你的异常处理,连接可能不会关闭,从而导致池资源耗尽,因此在第一次超时后你就会设置失败。 / p>

这并不完美,但更改为更合适可能会有所帮助。

    private static void WriteImage(MemoryStream ms, int RowId)
        {
            var conf = ConfigurationManager.ConnectionStrings["SQLconnString"].ToString();
            //Added using
            using(SqlConnection writecon = new SqlConnection(conf))
{

            writecon.Open();

            using (FileStream file = new FileStream("after.jpg", FileMode.Create, System.IO.FileAccess.Write))
            {
                file.Write(ms.ToArray(), 0, (int)ms.Length);
            }

            using (SqlCommand cmd = new SqlCommand("UPDATE InspectionItem SET strIIImage = @Image WHERE intIIID = @Id", writecon))
            {
                cmd.Parameters.Add("@Image", SqlDbType.VarBinary, (int)ms.Length).Value = ms.ToArray();
                cmd.Parameters.Add("@Id", SqlDbType.Int).Value = RowId;
                cmd.CommandTimeout = 5;
                try
                { //This is where it breaks. :)
                    cmd.ExecuteNonQuery();
                }
                catch (SqlException e)
                {
                    Writeout(e.Message + "Error occured on row: " + RowId);
                    return;
                }
            }
            Writeout("Succesfully Resized File: " + RowId);
            }
        }