PHP MYSQL防止在同时从不同用户插入时获取重复的唯一ID

时间:2016-02-11 06:26:11

标签: php mysql

我正在尝试在每张发票中生成发票ID,现在我有数千张发票,现在在同时从不同的ip添加我得到重复的发票ID如何防止它,

  

通过获取最后插入的发票ID并向其递增1来生成发票ID。

我的功能如下参数

void checkForRegisteredUser() {
        String url = "https://your_cloudant_user_name.cloudant.com/" + DB_NAME + "/" + DOC_ID;
        RequestQueue requestQueue = Volley.newRequestQueue(getContext());
        JsonObjectRequest jor = new JsonObjectRequest(Request.Method.GET, url, (String) null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                if (response.toString().length() > 0) {
                    setQuizData(response.toString());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                newUser();
            }
        });
        requestQueue.add(jor);

我的表格如下

get_new_tbl_id('table_name','invoice_id_column','string to strip (INV in INV0012)','any conditions');

function get_new_tbl_id($tbl_name,$id_field,$string,$options='')
{
$new_id = 0;
$query_count_rows = "SELECT MAX(CONVERT(replace(replace($id_field,',',''),'$string',''), SIGNED INTEGER)) as $id_field FROM $tbl_name WHERE $id_field LIKE '$string%'  $options";
$count_rows = mysql_query($query_count_rows);
$num_rows = mysql_num_rows($count_rows);
if($num_rows >0)
{
$last_row = mysql_fetch_assoc($count_rows);
$last_id = $last_row[$id_field];
$last_inserted_id = intval(str_replace($string,'',$last_id));
$new_id = $last_inserted_id+1;
}
else
$new_id = 1;
$format = '%1$03d';
$new_id=sprintf($format,$new_id,'');
return $string.$new_id;
}

2 个答案:

答案 0 :(得分:0)

使用myisam表为您生成2个字段的ID。第一个字段包含前缀(这是函数中的$ string),第二个字段应该是自动增量字段。在这两个字段上添加主键,但前缀字段必须是索引中的第一个。如果使用前缀在此表中插入新行,则mysql将增加该组中的自动增量值。

有关详细信息和示例,请参阅auto increment上mysql文档中的myisam notes部分。

CREATE TABLE animals (
    grp ENUM('fish','mammal','bird') NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

如果您的基表是mysql,那么只需更改它就可以获得此行为,如果没有,则创建一个单独的myisam表,先插入该表,然后获取主表中使用的ID。

答案 1 :(得分:0)

可能会有一些优化的解决方案,但现在我可以给你这个解决方案

使用static variable lock如果一个人获得了id $lock=true并等待其他请求等待1秒,请goto start;再次检查,直到第一次请求完成为止;最后制作$lock=false;以释放该功能。

public static $lock=false;

function get_new_tbl_id($tbl_name,$id_field,$string,$options='')
{
    global $lock;
    start:
    if($lock==true){
        sleep(1);
        goto start;
    }

    if($lock==false){
        $lock==true;
    }

    $new_id = 0;
    $query_count_rows = "SELECT MAX(CONVERT(replace(replace($id_field,',',''),'$string',''), SIGNED INTEGER)) as $id_field FROM $tbl_name WHERE $id_field LIKE '$string%'  $options";
    $count_rows = mysql_query($query_count_rows);
    $num_rows = mysql_num_rows($count_rows);
    if($num_rows >0)
    {
    $last_row = mysql_fetch_assoc($count_rows);
    $last_id = $last_row[$id_field];
    $last_inserted_id = intval(str_replace($string,'',$last_id));
    $new_id = $last_inserted_id+1;
    }
    else
    $new_id = 1;
    $format = '%1$03d';
    $new_id=sprintf($format,$new_id,'');

    $lock=false;

    return $string.$new_id;
}