关于activerecord:Subsonic 3.0.0.4泄漏SQL连接?

Subsonic 3.0.0.4 leaking SQL connections?

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

问题是执行该页面后,许多SQL连接在SQL Server中处于挂起/打开状态(通过查看sp_who2)。在页面完成执行之前,我得到"超时已到期。从池中获取连接之前已经经过了超时时间。这可能是因为所有池中的连接都在使用中,并且已达到最大池大小。"错误。

代码如下:

如果(string.IsNullOrEmpty(tbPeriodoAGenerar.Text))返回;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    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();
        }
    }

我做错了吗?此时,我不确定这是否是Subsonic错误,还是我需要以某种方式手动关闭连接。

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

有什么想法吗?任何帮助将不胜感激。


每次在基于ORM的对象上循环时,都必须考虑到可能存在N 1问题。我看不到您的模型,但我敢打赌,在您的循环中,您正在执行许多其他查询。

我知道Save()会触发并关闭ExecuteScalar()-这不应使连接保持打开状态。但是,如果要在该循环中获取相关记录,是的,可能会出现问题。

所以-我建议使用某种类型的探查器和调试器来逐步执行循环-查看进行了哪些查询。

或者-使用BatchInsert东西已经成熟了,它将使所有内容保持良好,整洁的单连接事务。

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