Increased auto field with stored procedure repeats

0

I have a problem with my system since I generate a self-incremented code in Mysql which works well when the system is used by only one user when using it 2 or 3 users this code that I generate automatically is repeated 3 times since its first creation until the last user there generated its sale.

To insert the sale I have the following in my mysql:

BEGIN       
        INSERT INTO venta(idtipodocumento,idcliente,idempleado,serie,numero,fecha,totalventa,igv,totalpagar,estado,descuento)
        VALUES(pidtipodocumento,pidcliente,pidempleado,pserie,pnumero,pfecha,ptotalventa,pigv,ptotalpagar,pestado,pdescuento);

    SELECT LAST_INSERT_ID() as idventa;
END

To get the last sales ID

BEGIN

    SELECT CONVERT(SUBSTRING( MAX( SUBSTRING(Numero, 2) ),5),UNSIGNED INTEGER ) AS id 
    FROM venta
    WHERE 1;
                            END

this code in php shows me the last id and generates a new one

public function generarNumVenta($idtipodoc=1) {

    $con = new clsConexion;
    if($con->conectarse()==true){
        $query = "CALL SP_S_UltimoIdVenta($idtipodoc)";
        $result = @mysql_query($query);
        while($array = mysql_fetch_array($result)){
            $ultimo_id_venta=$array['id']+1;
        }

    }
    $strNum_venta=str_pad((int) $ultimo_id_venta,10,"0",STR_PAD_LEFT);
    return $strNum_venta;

}

The problem is that when there is more than one user generating sales, this code is repeated and it is not wanted. If there are 3 users generating sales, this automatically generates example 0000000001, 0000000002, 0000000003 in the next sale 3 more users generated 3 sales 0000000004, 0000000005, 0000000006 and so on.

I apologize so much for the entanglement that someone could give a better question to get the best answer in the community, a greeting

    
asked by vdjkelly 20.10.2017 в 11:49
source

1 answer

1

The problem is the concurrency when your procedure is executed by more than one user returns the same number since there have been no changes in the table and CONVERT(SUBSTRING( MAX( SUBSTRING(Numero, 2) ),5),UNSIGNED INTEGER ) is the same, to solve it I recommend these options.

  • The procedure that obtains the last sales id records a sale without the data, confirm the transaction and then modify it so that when the next query arrives the max (numero) has already changed.

  • Create a separate table where you save the last sales id and the series per document and then modify the value of the last sales id.

  • You base the autoincremental of the invoice table to generate the sales id.

  • 4.You can also try to make the query CONVERT(SUBSTRING( MAX( SUBSTRING(Numero, 2) ),5),UNSIGNED INTEGER ) in the same insert

    I recommend the second option since you will have more control of your series, the first one I do not recommend it since you will have to delete the invoices of the transactions that go wrong and try to use transactions will not work as long as they do not confirm the other sessions can not see the changes so you'll have the same problem.

        
    answered by 20.10.2017 / 15:35
    source