none
Verificar si un id de particion (tabla particionada) se encuentra bloqueada RRS feed

  • Pregunta

  • hola amigos tengo una duda como puedo verificar si una partición se encuentra bloqueada,

    tengo una función de partición (0, 1)

    la tabla es esta

    id_partición     Dato

    -------------     --------

      0                   bbbbbb

      0                    rrrrrrrrr

      0                     wwwww

      1                     aaaaaaa

      1                    mmmmmm

    ------------------------------------------------

    necesito saber si la partición 0 se encuentra bloqueada(por varias transacciones), si fuese el caso los datos nuevos se inserten en la partición 1

    Gracias  

    viernes, 27 de abril de 2018 0:49

Todas las respuestas

  • Hola Diego Javier:

    No entiendo muy bien, porque si resulta que los datos, los quieres meter en una partición diferente a la que le toca, ¿entonces como sabrá Sql de donde tiene que obtener los datos?

    La idea de una partición es dividir, metiendo los datos organizados, en función de un criterio. Por ejemplo un rango de fechas. Pero si la causistica dice, que cuando ocurra no se que problema, ya no van a esa partición, entonces el rango esta roto, y la función de partición se iría al garete.

    Desde mi más absoluta ignorancia, creo que tienes que darle una vuelta al asunto. O buscar como evitar o mejorar los procesos, que bloquean y porque las transacciones.

    Saludos

    viernes, 27 de abril de 2018 5:49
  • Muchas gracias por la pronta respuesta Javi.

    posiblemente no explique bien mi pregunta, procederé a explicarla nuevamente:

    Tengo una tabla en la cual se introducen millones de registros, uno por uno, todos dentro de un bucle y todo dentro de una transacción (commit o rollback), el problema es que mientras se ejecuta este proceso la tabla queda bloqueada y no permite hacer otras inserciones paralelas, es aquí donde nace la idea de particionar la tabla, como ejemplo puse dos particiones, y la función de partición esta en base a un valor que puede ser 0 o 1.

    Lo que necesito hacer es, que cuando empiece a llegar el lote de registros, antes de empezar a introducirlos, yo identifique que partición NO esta bloqueada para usar esa y que los registros sean sobre la misma, en pseudo-codigo ejemplifico:

    if(Partición0 esta bloqueada)
    {
       if(partición1 esta bloqueada)
       {
          mensaje: intente mas tarde
       }
       else
       {
          registramos en partición1
       }
    }
    else
    {
       registramos en particion0
    }

    Bueno, espero que ahora si este mas clara mi duda y puedan colaborarme.

    Saludos cordiales.

    viernes, 27 de abril de 2018 14:42
  • Hola Diego:

    Y que tal, si te apoyas en otra tabla.

    TablaSemaforo.

    Donde solo tiene un registro y su estado y su fecha de ultimo estado, de manera, que el estado es o INICIADO, TERMINADO. Cuando inicio el proceso (justo antes), cambio el estado.

    INICIO PROCESO.

    Si llega otro lote, pregunta primero en estado y como estado =  INICIADO, espera.

    Cuando termino, estado TERMINADO.

    Te digo en una tabla con una fila, para que tengas que hacer una simple update, porque la update no puede ocurrir que te diga una cosa mientras esta apunto de ocurrir y tengas una colisión de dos intentos simultaneos.

    Creo que es más fácil, y te dará mayor control.

    Luego ya si quieres tener una tabla adyacente, como AUDITORIAS_ESTADO, donde logueas los intentos, genial.

    Es un sistema simple, y te costará poco implementarlo.

    viernes, 27 de abril de 2018 17:49
  • Hola Diego Javier:

    El sistema podría ser algo así

    create table PROCESO (ID INT, ESTADO BIT)
    GO
    INSERT INTO dbo.PROCESO (ID,ESTADO) VALUES (1,0)
    GO
    
    CREATE PROCEDURE [dbo].CAMBIAR_ESTADO 
    AS
    BEGIN
    	BEGIN TRANSACTION
    	DECLARE @ESTADO BIT;
    	
    		UPDATE PROCESO SET ESTADO = ~ ESTADO
    		IF (@@ERROR=0)
    		
    			COMMIT TRANSACTION
    		ELSE
    			ROLLBACK TRANSACTION;
    	END
    	
    RETURN
    
    
    go
    CREATE FUNCTION DBO.CualEsMiSemaforo ()
    RETURNS BIT
    AS
    BEGIN
    	RETURN (SELECT ESTADO FROM PROCESO);
    END;
    
    GO
    CREATE PROCEDURE INICIOPROCESO
    AS
    BEGIN
    begin try
    	DECLARE @ESTADO BIT = 0;
    	
    	if (dbo.CualEsMiSemaforo()=0)
    	begin
    		EXEC CAMBIAR_ESTADO;
    		SET @ESTADO = 1;
    		print 'inicio proceso'
    
    
    		/*CUANDO FINALIZO PROCESO*/
    		EXEC CAMBIAR_ESTADO;
    	end
    	else
    	begin
    		print 'estado espera'
    	end
    end try
    begin catch
    	IF @ESTADO =1
    		BEGIN
    			/* COMO LA INSERCCION HA TENIDO PROBLEMAS, DESBLOQUEO EL ESTADO DE INSERCCION PARA OTRO PRCESO */
    			EXEC CAMBIAR_ESTADO;
    		END
    end catch
    END;
    
    

    Un saludo

    sábado, 28 de abril de 2018 9:02
  • No soy DBA así que esto está fuera de mi usual alcance, pero hasta donde recuerdo, la partición se basa en un valor.  Entonces en teoría sería cuestión de manipular dicho valor para así poder comandar en qué partición se escribe.  Lo que no sé es si SQL Server permitirá el acceso o no.  Dependiendo de la forma que se programe la inserción, tal vez toda la tabla esté bloqueda, sin importar la partición a la que se escriba.

    En fin, suponiendo que eso sirve, yo tendría una tabla auxiliar con una cantidad definida de registros:  Uno por partición.  Cada registro tendría el campo de estado que Javi propone.  Luego entonces sería cuestión de consultar esta tabla para saber qué particiones están inactivas y escoger una de ellas.


    Jose R. MCP
    Code Samples

    martes, 1 de mayo de 2018 9:15