none
Servicios WCF - error de concurrencia RRS feed

  • Pregunta

  • He desarrollado un servicio con WSSF y C#, tengo un problema cuando ejecuto una operación al mismo tiempo:

    Ejecuto un SP en informix y al ejecutar el servicio dos veces al mismo tiempo me sale error en una de ellas por Informix, utilicé AsyncPattern de esta manera para controlar la asincronía pero el error persiste, alguna ayuda por favor

    public override IAsyncResult BeginEmitirPoliza(SOAT.MessageContracts.EmitirPolizaRequest request, AsyncCallback callback, object state)
            {
                PolizaBE PolizaBE = new PolizaBE();
                DireccionBE DireccionBE = new DireccionBE();
                VehiculoBE VehiculoBE = new VehiculoBE();
                MensajeBE MensajeBE = new MensajeBE();
                PersonaBE PersonaBE = new PersonaBE();
    
                try
                {
                    ManejadorError.ValidateAttributes(request);
    
                    PolizaBE.FechaInicio = request.DatosPoliza.FechaInicio;
                    PolizaBE.FechaFin = request.DatosPoliza.FechaFin;
                    PolizaBE.IdRamo = request.DatosPoliza.IdRamo;
                    PolizaBE.IdProducto = request.DatosPoliza.IdProducto;
                    PolizaBE.IdClienteVtime = request.DatosPoliza.IdCliente;
                    PolizaBE.Monto = request.DatosPoliza.Prima;
                    PolizaBE.NumeroTicket = request.DatosPoliza.NumeroTicket;
                    PolizaBE.IdPoliza = request.DatosPoliza.IdPoliza;
    
                    PolizaBE.IdEnvio = request.DatosPoliza.DatosEnvio.IdEnvio;
                    PolizaBE.FechaEnvio = request.DatosPoliza.DatosEnvio.Fecha;
                    PolizaBE.HoraEnvio = request.DatosPoliza.DatosEnvio.Hora;
                    PolizaBE.CodigoAutorizacion = request.DatosPoliza.CodigoAutorizacion;
    
                    DireccionBE.DescripcionDireccion = request.DatosPoliza.DatosEnvio.Direccion;
                    DireccionBE.Referencia = request.DatosPoliza.DatosEnvio.Referencia;
                    DireccionBE.IdDepartamento = request.DatosPoliza.DatosEnvio.Ubigeo.IdDepartamento;
                    DireccionBE.IdProvincia = request.DatosPoliza.DatosEnvio.Ubigeo.IdProvincia;
                    DireccionBE.IdDistrito = request.DatosPoliza.DatosEnvio.Ubigeo.IdDistrito;
    
                    VehiculoBE.Placa = request.DatosPoliza.Vehiculo.NumeroPlaca;
                    VehiculoBE.AnioFabricacion = request.DatosPoliza.Vehiculo.AnioFabricacion;
                    VehiculoBE.ClasVehiculo = request.DatosPoliza.Vehiculo.IdClase;
                    VehiculoBE.Chasis = request.DatosPoliza.Vehiculo.Chasis;
                    VehiculoBE.Descripcion = request.DatosPoliza.Vehiculo.Descripcion;
                    VehiculoBE.GrupoVehiculo = request.DatosPoliza.Vehiculo.IdUso;
                    VehiculoBE.NroAsientos = request.DatosPoliza.Vehiculo.NumeroAsientos;
                    VehiculoBE.SerieMotor = request.DatosPoliza.Vehiculo.SerieMotor;
                    VehiculoBE.TipoTimon = request.DatosPoliza.Vehiculo.TipoTimon;
                    VehiculoBE.IdVersion = request.DatosPoliza.Vehiculo.IdVersion;
                    MensajeBE = _PolizaBL.EmitirPoliza(PolizaBE, DireccionBE, VehiculoBE);
                    
                    return new CompletedAsyncResult<MensajeBE>(MensajeBE);
                }
                catch (Exception ex)
                {
                    SOATFaultContract SOATFC = new SOATFaultContract();
                    SOATFC.Mensaje = ex.Message;
                    throw new WCF.FaultException<SOATFaultContract>(SOATFC, "Error en Servicio SOAT: Operacion Emitir Poliza");
                }
    
                
    
            }
    
            public override EmitirPolizaResponse EndEmitirPoliza(IAsyncResult r)
            {
                EmitirPolizaResponse response = new EmitirPolizaResponse();
    
                CompletedAsyncResult<MensajeBE> result = r as CompletedAsyncResult<MensajeBE>;
                MensajeBE MensajeBE = result.Data;
                response.Mensaje = TranslateBetweenMensajeAndMensajeBE.TranslateMensajeBEToMensaje(MensajeBE);
                
                return response;
            }

    miércoles, 18 de noviembre de 2015 20:50

Respuestas

  • Hola. He visto que en tu pregunta, en el código que has mostrado asignas al objeto de tipo PolizaBE en su propiedad Id ya el numero de poliza de un request. Ahí esta el problema.

    PolizaBE.IdPoliza = request.DatosPoliza.IdPoliza;

    cómo se carga ese IdPoliza en el request? Tal vez deberías ver por ahí la causa. Espero explicarme


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    viernes, 20 de noviembre de 2015 5:43
    Moderador

Todas las respuestas

  • Para manejar la concurrencia WCF te ofrece lo siguiente para modificar en el ServiceBehaviour

    Echa un ojo a estos enlace

    WCF Concurrency (Single, Multiple, and Reentrant) and Throttling

    Sessions, Instancing and Concurrency in WCF Services

    ServiceBehaviorAttribute Class

    Default Service Behavior


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 19 de noviembre de 2015 8:45
    Moderador
  • Sergio, de antemano gracias por la atención.

    He revisado cada una de la documentación que me pasaste, hice algunas modificaciones en el código y aun persiste el error. Te cuento un poco más para ver si me puedes dar una opinión menos genérica.

    El servicio genera un registro en la BD que debe ser correlativo, ahora uso dos SP, uno con el cual obtengo el correlativo y en la segundo lo inserto ( No puedo manipular para hacerlo todo en uno porque son SP's corporativos y no se me permite su modificación).

    Entonces, al ejecutar el servicio al mismo tiempo, siempre sale uno bien y el otro vota error (esto no debería pasar) y debugueando el error me sale al ejecutar el SP de inserción.

    A la espera de tus comentarios.

    Saludos.

    jueves, 19 de noviembre de 2015 15:53
  • Qué error te da??

    Tal vez clave duplicada?  Deberís implementar una transacción en tu SP para bloquear la tabla a la que insertas "temporalmente". Pero como no puedes tocarlos te recomiendo implementes transacción en tu código .NET empleando TransactionScope dentro de EmitirPoliza

    MensajeBE = _PolizaBL.EmitirPoliza(PolizaBE, DireccionBE, VehiculoBE);

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 19 de noviembre de 2015 16:09
    Moderador
  • Sergio, he intentado implementarlo, y me sigue saliendo el error.

    Hay algo que me esté faltando?

     void IPolizaDA.EmitirCertificado(PolizaBE PolizaBE, PersonaBE PersonaBE, VehiculoBE VehiculoBE, DireccionBE DireccionBE)
            {
                ConnectionStringSettings strConnString = ConfigurationManager.ConnectionStrings["Insunix"];
    
                try
                {
                    using (TransactionScope scope = new TransactionScope())
                    {
                        using (IfxConnection con = new IfxConnection(strConnString.ConnectionString))
                        {
    
                            con.Open();
    
                            IfxCommand cmd = new IfxCommand();
                            cmd.Connection = con;
                            cmd.CommandType = CommandType.StoredProcedure;
                            cmd.CommandText = "get_certif";
    
                            cmd.Parameters.Add("p_branch", IfxType.Integer).Value = PolizaBE.IdRamo;
                            cmd.Parameters.Add("p_policy", IfxType.Integer).Value = PolizaBE.IdPoliza;
    
                            IfxDataReader reader = cmd.ExecuteReader();
    
                            while (reader.Read())
                            {
                                PolizaBE.IdCertificado = reader[0].ToString().Trim() == "" ? 0 : Convert.ToInt32(reader[0].ToString().Trim());
                            }
    
                            Util.Error.Funciones.validarConexionInformix(con);
    
                            using (IfxConnection con2 = new IfxConnection(strConnString.ConnectionString))
                            {
                                con2.Open();
    
                                IfxCommand cmd2 = new IfxCommand();
                                cmd2.Connection = con2;
                                cmd2.CommandType = CommandType.StoredProcedure;
                                cmd2.CommandText = "INFORMIX.VAL_SOAT_CERTIF";
    
    
                                if (PersonaBE.TipoDocumento == 1)
                                {
                                    cmd2.Parameters.Add("p_tipper", IfxType.Char, 1).Value = "N";
                                    cmd2.Parameters.Add("p_ruccon", IfxType.Char, 12).Value = DBNull.Value;
                                    cmd2.Parameters.Add("p_dnicon", IfxType.Char, 12).Value = PersonaBE.NumeroDocumento.Trim();
                                }
                                else
                                {
                                    cmd2.Parameters.Add("p_tipper", IfxType.Char, 1).Value = "J";
                                    cmd2.Parameters.Add("p_dnicon", IfxType.Char, 12).Value = DBNull.Value;
                                    cmd2.Parameters.Add("p_ruccon", IfxType.Char, 12).Value = PersonaBE.NumeroDocumento.Trim(); ;
                                }
    
                                cmd2.Parameters.Add("p_cliename", IfxType.Char, 40).Value = PersonaBE.Nombre.Trim();
                                cmd2.Parameters.Add("p_codsex", IfxType.Char, 1).Value = PersonaBE.Sexo;
                                cmd2.Parameters.Add("p_street", IfxType.Char, 40).Value = DireccionBE.DescripcionDireccion;
    
                                cmd2.Parameters.Add("p_zipcode", IfxType.Char, 6).Value = 0;
                                cmd2.Parameters.Add("p_phone1", IfxType.Char, 12).Value = string.Empty;
                                cmd2.Parameters.Add("p_phone2", IfxType.Char, 12).Value = string.Empty;
    
                                cmd2.Parameters.Add("p_email", IfxType.Char, 50).Value = string.Empty;
                                cmd2.Parameters.Add("p_poliza", IfxType.Integer).Value = PolizaBE.IdPoliza;
                                cmd2.Parameters.Add("p_intermed", IfxType.Integer).Value = PolizaBE.IdIntermediario;
    
                                cmd2.Parameters.Add("p_effecdate", IfxType.Date).Value = PolizaBE.FechaInicio;
                                cmd2.Parameters.Add("p_expirdat", IfxType.Date).Value = PolizaBE.FechaFin;
                                cmd2.Parameters.Add("p_emisdate", IfxType.Date).Value = DateTime.Today;
    
                                cmd2.Parameters.Add("p_premium", IfxType.Decimal).Value = PolizaBE.Monto;
                                cmd2.Parameters.Add("p_vehcode", IfxType.Integer).Value = VehiculoBE.IdVersion;//A que hace referencia
                                cmd2.Parameters.Add("p_regist", IfxType.Char, 10).Value = VehiculoBE.Placa;
    
                                cmd2.Parameters.Add("p_vehplace", IfxType.SmallInt).Value = VehiculoBE.NroAsientos;
                                cmd2.Parameters.Add("p_chassis", IfxType.Char, 22).Value = VehiculoBE.Chasis;//Descipcion de CHASIS
                                cmd2.Parameters.Add("p_year", IfxType.SmallInt).Value = VehiculoBE.AnioFabricacion;
    
                                cmd2.Parameters.Add("p_motor", IfxType.Char, 22).Value = VehiculoBE.SerieMotor;
                                cmd2.Parameters.Add("p_vehgroup", IfxType.Char, 2).Value = VehiculoBE.GrupoVehiculo;
                                cmd2.Parameters.Add("p_vehclass", IfxType.Char, 2).Value = VehiculoBE.ClasVehiculo;
    
                                cmd2.Parameters.Add("p_vehtar", IfxType.Char, 1).Value = PolizaBE.TipoTarifaSoat;//COnfiguracion
                                cmd2.Parameters.Add("p_exchange", IfxType.Decimal).Value = PolizaBE.TipoCambio;//Configuracion
                                cmd2.Parameters.Add("p_office", IfxType.SmallInt).Value = PolizaBE.Oficina;
    
                                cmd2.Parameters.Add("p_type_commi", IfxType.Decimal).Value = PolizaBE.TipoComision;//Configuracion
                                cmd2.Parameters.Add("p_usercode", IfxType.SmallInt).Value = PolizaBE.IdUsuario;//
                                cmd2.Parameters.Add("p_proceso", IfxType.Char, 1).Value = PolizaBE.IdAccion;//Configuracion
    
                                cmd2.Parameters.Add("p_contrat", IfxType.Char, 11).Value = PolizaBE.IdClienteInsunix;
                                cmd2.Parameters.Add("p_zipcodezona", IfxType.Char, 6).Value = DireccionBE.CodigoZIP;
    
                                cmd2.Parameters.Add("p_currency", IfxType.SmallInt).Value = PolizaBE.IdMoneda;
                                cmd2.Parameters.Add("p_client_vt", IfxType.Char, 14).Value = string.Empty;
                                cmd2.Parameters.Add("p_asegurado", IfxType.Char, 11).Value = PolizaBE.IdClienteInsunix;
    
                                cmd2.Parameters.Add("p_des_model", IfxType.Char, 30).Value = DBNull.Value;
                                cmd2.Parameters.Add("p_type_helm", IfxType.SmallInt).Value = DBNull.Value;
    
                                cmd2.Parameters.Add("p_certif", IfxType.Integer).Value = PolizaBE.IdCertificado;
                                cmd2.Parameters.Add("p_commision", IfxType.Decimal).Value = PolizaBE.Comision;
    
                                cmd2.Parameters.Add("p_typ_inter", IfxType.Integer).Value = PolizaBE.TipoIntermediario;
                                cmd2.Parameters.Add("p_intermed_dir", IfxType.Integer).Value = PolizaBE.IdIntermediario;
                                cmd2.Parameters.Add("p_commis_dir", IfxType.Decimal).Value = PolizaBE.PorcentajeComision;
    
                                cmd2.Parameters.Add("p_empleado", IfxType.Char, 14).Value = DBNull.Value;//0
                                cmd2.Parameters.Add("p_rxgc_percent", IfxType.Decimal).Value = DBNull.Value;//0
                                cmd2.Parameters.Add("p_rxgc_com_cant", IfxType.Integer).Value = DBNull.Value;//  
    
                                cmd2.Parameters.Add("p_rxgc_com_dat", IfxType.Char, 150).Value = string.Empty;
                                cmd2.Parameters.Add("p_rxgc_ori_matriz", IfxType.SmallInt).Value = DBNull.Value;
    
                                IfxDataReader reader2 = cmd2.ExecuteReader();
    
                                while (reader2.Read())
                                {
                                    PolizaBE.IdRecibo = reader2[1].ToString().Trim() == "" ? 0 : Convert.ToInt32(reader2[1].ToString().Trim());
                                }
                                Util.Error.Funciones.validarConexionInformix(con2);
                            }
                        }
                        scope.Complete();
                    }
                }
                catch
                {
                    throw new Exception("Error al emitir certificado") { Source = "D0013" };
                }
            }

    jueves, 19 de noviembre de 2015 17:48
  • puedes especificarnos el mensaje de error que obtienes? Gracias

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 19 de noviembre de 2015 20:46
    Moderador
  • ERROR [23000] [Informix .NET provider][Informix]Unique constraint (informix.u127_15) violated.

    Es claro que es porque Clave Duplicada. Los SP's se ejecutan tal y como te mostré  en el mensaje anterior.

    No hay alguna forma de hacer que cuando termine toda esa ejecución dentro del TransactionScope  recien entre la otra? Porque al parece está ejecutando dos veces el primer SP y por ende obtiene la misma clave para los dos y cuando intenta hacer la segunda inserción la clave ya ha sido insertada.

    Por favor tu apoyo

    jueves, 19 de noviembre de 2015 21:00
  • Hola. Estas seguro si ese error de clave duplicada es por la clave primaria? Me refiero a ver si da error por otro campo relacionado.... Espero explicarme. Puedes poner el código de cómo capturar el correlativo?


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 19 de noviembre de 2015 23:15
    Moderador
  • Hola. He visto que en tu pregunta, en el código que has mostrado asignas al objeto de tipo PolizaBE en su propiedad Id ya el numero de poliza de un request. Ahí esta el problema.

    PolizaBE.IdPoliza = request.DatosPoliza.IdPoliza;

    cómo se carga ese IdPoliza en el request? Tal vez deberías ver por ahí la causa. Espero explicarme


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    viernes, 20 de noviembre de 2015 5:43
    Moderador
  • Hola. He marcado una respuesta. Si no es correcta desmarcala y comenta si has podido o no solucionar tu problema ok? GRacias

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    lunes, 23 de noviembre de 2015 8:01
    Moderador