Subsonic 3.0.0.4泄漏SQL连接?

时间:2012-07-20 17:46:18

标签: activerecord connection-pooling subsonic3 connection-leaks

我一直在使用Subsonic 3.0.0.4(ActiveRecord方法)一段时间,我最近编写了一个小页面,它基本上检索了给定年份的大约500条记录,然后我只是遍历每一条记录,创建新的Active Record类的实例,只修改Period字段,并在循环中保存每个实例。

问题是在执行该页面后,SQL服务器中挂起/打开了很多SQL连接(通过查看sp_who2)。在页面完成执行之前,我得到“Timeout expired。在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。”错误。

代码如下:

if(string.IsNullOrEmpty(tbPeriodoAGenerar.Text))return;

    var idPeriodo = Convert.ToInt32(tbPeriodoAGenerar.Text);



    var nuevaEncuesta = new Encuesta();

    nuevaEncuesta.IdPeriodo = idPeriodo;
    nuevaEncuesta.IdResponsable = 1;
    nuevaEncuesta.fechaCierre1 = Convert.ToDateTime(dpFechaCierre1.Value);
    nuevaEncuesta.fechaCierre2 = Convert.ToDateTime(dpFechaCierre2.Value);
    nuevaEncuesta.IdTipoEncuesta = (int)ETipoEncuesta.PorAnio;
    nuevaEncuesta.nombreEncuesta = NombresEncuestas.COVA;
    nuevaEncuesta.nombrePublico = NombresEncuestas.COVA_PUBLICO;

    nuevaEncuesta.Save();


    var empresasActivas = Empresa.Find(x => x.activo == 1);

    foreach (var empresa in empresasActivas)
    {
        EmpresaEncuesta ee = new EmpresaEncuesta();

        ee.IdEmpresa = empresa.IdEmpresa;
        ee.IdEncuesta = nuevaEncuesta.IdEncuesta;
        ee.IdEstatusContestado = (int)EEstatusEmpresaEncuesta.SinContestar;
        ee.fechaMod = DateTime.Now;
        ee.IdUsuario = 1;
        ee.ipMod = IpUsuarioActual;
        ee.Save();
    }


    if (chkMigrarRespuestas.Checked)
    {


        var periodosAnteriores = new EncuestaBO().ObtenerPeriodosAnteriores(NombresEncuestas.COVA, idPeriodo);
        int? periodoAnterior = null;

        if (periodosAnteriores.Tables[0].Rows.Count > 0)
        {
            periodoAnterior = Convert.ToInt32(periodosAnteriores.Tables[0].Rows[0][Columnas.ID_PERIODO]);
        }

        if (!periodoAnterior.HasValue) return;


        var respuestasCortoPlazo = COVACortoPlazo.Find(x => x.Periodo == (periodoAnterior));
        COVACortoPlazo ccp;

        foreach (var ccpAnterior in respuestasCortoPlazo)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == ccpAnterior.IdEmpresa).Any()) continue;

            ccp = new COVACortoPlazo();

            ccp.IdEmpresa = ccpAnterior.IdEmpresa;
            ccp.CuentaCortoPlazo = ccpAnterior.CuentaCortoPlazo;
            ccp.ComentariosAdicionales = ccpAnterior.ComentariosAdicionales;
            ccp.RetiroVoluntarioOpcionId = ccpAnterior.RetiroVoluntarioOpcionId;
            ccp.RetiroVoluntarioOtroDesc = ccpAnterior.RetiroVoluntarioOtroDesc;
            ccp.RetiroEmpresaOpcionId = ccpAnterior.RetiroEmpresaOpcionId;
            ccp.RetiroEmpresaOtroDesc = ccpAnterior.RetiroEmpresaOtroDesc;

            ccp.Periodo = idPeriodo;

            ccp.Save();
        }



        var tablaCortoPlazoAnterior = COVATablaCortoPlazo.Find(x => x.Periodo == (periodoAnterior));
        COVATablaCortoPlazo ctcp;

        foreach (var ctcpAnterior in tablaCortoPlazoAnterior)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == ctcpAnterior.IdEmpresa).Any()) continue;

            ctcp = new COVATablaCortoPlazo();

            ctcp.IdEmpresa = ctcpAnterior.IdEmpresa;
            ctcp.Periodo = idPeriodo;

            ctcp.COVASegmentoOpcionId = ctcpAnterior.COVASegmentoOpcionId;
            ctcp.NivelDinamicaMin = ctcpAnterior.NivelDinamicaMin;
            ctcp.NivelDinamicaMax = ctcpAnterior.NivelDinamicaMax;

            ctcp.NombreBono = ctcpAnterior.NombreBono;
            ctcp.COVAPeriodicidadOpcionId = ctcpAnterior.COVAPeriodicidadOpcionId;
            ctcp.MetodoCalculo = ctcpAnterior.MetodoCalculo;
            ctcp.COVABaseCalculoOpcionId = ctcpAnterior.COVABaseCalculoOpcionId;
            ctcp.RealAnualizado = ctcpAnterior.RealAnualizado;

            ctcp.Save();
        }



        var respuestasAnual = COVAAnual.Find(x => x.Periodo == (periodoAnterior));
        COVAAnual ca;

        foreach (var caAnterior in respuestasAnual)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == caAnterior.IdEmpresa).Any()) continue;

            ca = new COVAAnual();

            ca.IdEmpresa = caAnterior.IdEmpresa;
            ca.CuentaAnual = caAnterior.CuentaAnual;
            ca.NombreBono = caAnterior.NombreBono;
            ca.FechaPago = caAnterior.FechaPago;

            ca.ComentariosAdicionales = caAnterior.ComentariosAdicionales;

            ca.RetiroVoluntarioOpcionId = caAnterior.RetiroVoluntarioOpcionId;
            ca.RetiroVoluntarioOtroDesc = caAnterior.RetiroVoluntarioOtroDesc;
            ca.RetiroEmpresaOpcionId = caAnterior.RetiroEmpresaOpcionId;
            ca.RetiroEmpresaOtroDesc = caAnterior.RetiroEmpresaOtroDesc;

            ca.Periodo = idPeriodo;

            ca.Save();
        }



        var tablaAnualAnterior = COVATablaAnual.Find(x => x.Periodo == (periodoAnterior));
        COVATablaAnual cta;

        foreach (var ctaAnterior in tablaAnualAnterior)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == ctaAnterior.IdEmpresa).Any()) continue;

            cta = new COVATablaAnual();

            cta.IdEmpresa = ctaAnterior.IdEmpresa;
            cta.Periodo = idPeriodo;

            cta.COVASegmentoOpcionId = ctaAnterior.COVASegmentoOpcionId;
            cta.NivelDinamicaMin = ctaAnterior.NivelDinamicaMin;
            cta.NivelDinamicaMax = ctaAnterior.NivelDinamicaMax;

            cta.Minimo = ctaAnterior.Minimo;
            cta.Target = ctaAnterior.Target;
            cta.Maximo = ctaAnterior.Maximo;

            cta.RealAnualPagado = ctaAnterior.RealAnualPagado;
            cta.MetodoCalculo = ctaAnterior.MetodoCalculo;
            cta.COVABaseCalculoOpcionId = ctaAnterior.COVABaseCalculoOpcionId;

            cta.Save();
        }



        var respuestasLargoPlazo = COVALargoPlazo.Find(x => x.Periodo == (periodoAnterior));
        COVALargoPlazo clp;

        foreach (var clpAnterior in respuestasLargoPlazo)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == clpAnterior.IdEmpresa).Any()) continue;

            clp = new COVALargoPlazo();

            clp.IdEmpresa = clpAnterior.IdEmpresa;
            clp.CuentaLargoPlazo = clpAnterior.CuentaLargoPlazo;
            clp.ComentariosAdicionales = clpAnterior.ComentariosAdicionales;

            clp.RetiroVoluntarioOpcionId = clpAnterior.RetiroVoluntarioOpcionId;
            clp.RetiroVoluntarioOtroDesc = clpAnterior.RetiroVoluntarioOtroDesc;
            clp.RetiroEmpresaOpcionId = clpAnterior.RetiroEmpresaOpcionId;
            clp.RetiroEmpresaOtroDesc = clpAnterior.RetiroEmpresaOtroDesc;

            clp.PermiteCompraAcciones = clpAnterior.PermiteCompraAcciones;

            clp.Periodo = idPeriodo;

            clp.Save();
        }



        var tablaLargoPlazoAnterior = COVATablaLargoPlazo.Find(x => x.Periodo == (periodoAnterior));
        COVATablaLargoPlazo ctlp;

        foreach (var ctlpAnterior in tablaLargoPlazoAnterior)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == ctlpAnterior.IdEmpresa).Any()) continue;

            ctlp = new COVATablaLargoPlazo();

            ctlp.IdEmpresa = ctlpAnterior.IdEmpresa;
            ctlp.Periodo = idPeriodo;

            ctlp.NombrePlan = ctlpAnterior.NombrePlan;
            ctlp.COVATipoPlanOpcionId = ctlpAnterior.COVATipoPlanOpcionId;


            ctlp.COVASegmentoOpcionId = ctlpAnterior.COVASegmentoOpcionId;
            ctlp.NivelDinamicaMin = ctlpAnterior.NivelDinamicaMin;
            ctlp.NivelDinamicaMax = ctlpAnterior.NivelDinamicaMax;


            ctlp.RealPagadoFinalPlan = ctlpAnterior.RealPagadoFinalPlan;
            ctlp.AniosEjerce = ctlpAnterior.AniosEjerce;
            ctlp.MetodoCalculo = ctlpAnterior.MetodoCalculo;
            ctlp.BaseCalculo = ctlpAnterior.BaseCalculo;

            ctlp.Save();
        }


        var respuestasVentas = COVAVentas.Find(x => x.Periodo == (periodoAnterior));
        COVAVentas cv;

        foreach (var cvAnterior in respuestasVentas)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == cvAnterior.IdEmpresa).Any()) continue;

            cv = new COVAVentas();

            cv.IdEmpresa = cvAnterior.IdEmpresa;
            cv.CuentaVentas = cvAnterior.CuentaVentas;
            cv.ComentariosAdicionales = cvAnterior.ComentariosAdicionales;

            cv.RetiroVoluntarioOpcionId = cvAnterior.RetiroVoluntarioOpcionId;
            cv.RetiroVoluntarioOtroDesc = cvAnterior.RetiroVoluntarioOtroDesc;
            cv.RetiroEmpresaOpcionId = cvAnterior.RetiroEmpresaOpcionId;
            cv.RetiroEmpresaOtroDesc = cvAnterior.RetiroEmpresaOtroDesc;

            cv.Periodo = idPeriodo;

            cv.Save();
        }




        var tablaVentasAnterior = COVATablaVentas.Find(x => x.Periodo == (periodoAnterior));
        COVATablaVentas ctv;

        foreach (var ctvAnterior in tablaVentasAnterior)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == ctvAnterior.IdEmpresa).Any()) continue;

            ctv = new COVATablaVentas();

            ctv.IdEmpresa = ctvAnterior.IdEmpresa;
            ctv.Periodo = idPeriodo;

            ctv.COVASegmentoOpcionId = ctvAnterior.COVASegmentoOpcionId;
            ctv.COVAPeriodicidadOpcionId = ctvAnterior.COVAPeriodicidadOpcionId;

            ctv.Minimo = ctvAnterior.Minimo;
            ctv.Target = ctvAnterior.Target;
            ctv.Maximo = ctvAnterior.Maximo;

            ctv.RealAnualizado = ctvAnterior.RealAnualizado;
            ctv.MetodoCalculo = ctvAnterior.MetodoCalculo;
            ctv.BaseCalculo = ctvAnterior.BaseCalculo;

            ctv.Save();
        }




        var respuestasGenerales = COVAGenerales.Find(x => x.Periodo == (periodoAnterior));
        COVAGenerales cg;

        foreach (var cgAnterior in respuestasGenerales)
        {
            if (!empresasActivas.Where(emp => emp.IdEmpresa == cgAnterior.IdEmpresa).Any()) continue;

            cg = new COVAGenerales();

            cg.IdEmpresa = cgAnterior.IdEmpresa;

            cg.AccionesPorSituacionActual = cgAnterior.AccionesPorSituacionActual;
            cg.ComentariosAccionesSituacionActual = cgAnterior.ComentariosAccionesSituacionActual;
            cg.TomaCuentaSituacionDefinicionObjetivos = cgAnterior.TomaCuentaSituacionDefinicionObjetivos;


            cg.Periodo = idPeriodo;

            cg.Save();
        }
    }

我做错了吗?此时,我不确定这是否是一个亚音速错误,或者我是否需要以某种方式手动关闭连接。

在使用亚音速时,我搜索了有关类似问题的帖子,但没有一个出现过。我得到错误的常见原因是没有关闭SqlDataReader,但老实说我不相信Subsonic没有关闭它......我使用的是最新版本。

有什么想法吗?非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

每当你对基于ORM的对象进行循环时,你必须考虑可能存在N + 1问题。我看不到你的模型,但我敢打赌,在你的循环中,你正在执行一些额外的查询。

我知道Save()会触发并关闭一个ExecuteScalar() - 这不应该打开一个连接。但是,如果您在该循环中获取相关记录 - 是的,那可能会有问题。

所以 - 我建议使用某种类型的探查器和调试器来逐步完成循环 - 看看有什么查询。

或者 - 这对于使用BatchInsert的东西来说已经成熟,它可以将所有内容保存在一个漂亮,整洁的单连接事务中。

请阅读此处了解更多信息: http://subsonic.wekeroad.com/docs/Linq_Inserts