Генерация уникального случайного числа и его сохранение в соответствии с пользовательским порядком - обработка запросов одновременно? - PullRequest
0 голосов
/ 15 января 2019

Я использую приведенную ниже функцию для генерации уникального случайного числа, когда клиенты завершают заказ в Woocommerce и сохраняют его в массиве, чтобы другой клиент не мог его сгенерировать. Я вызываю функцию на хуке woocommerce_order_processing.

Мне просто интересно узнать, насколько пуленепробиваемым является это решение и как оно будет обрабатывать заказы нескольких клиентов одновременно? Возможно ли, что они получат одинаковое число или база данных сможет вернуть используемый массив чисел достаточно быстро?

function add_lottery_ticket_number( $postId ) {
    if (metadata_exists('post', $postId, 'optionsToGive')) {
        $ticketOptions = get_post_meta( $postId, 'optionsToGive', true );
    } else {
        $lottery_max_tickets = get_post_meta( $postid, '_max_tickets', true );
        $ticketOptions = range(1, $lottery_max_tickets);
        shuffle($ticketOptions ); //random order of all number
    }
    $ticketAllocated = array_shift($ticketOptions); //take the first element
    update_post_meta( $postId, 'optionsToGive', $ticketOptions ); //update all the rest
    return $ticketAllocated;
}

for ( $i = 0; $i < $item_meta['_qty'][0]; $i++ ) {
    add_post_meta( $product_id, '_participant_id', $order->get_user_id() );
    $participants = get_post_meta( $product_id, '_lottery_participants_count', true ) ? get_post_meta( $product_id, '_lottery_participants_count', true ) : 0;
    update_post_meta( $product_id, '_lottery_participants_count', intval( $participants ) + 1 );
    $this->add_lottery_to_user_metafield( $product_id, $order->get_user_id() );
    $ticketnumber = $this->add_lottery_ticket_number($product_id);
    $log_ids[] = $this->log_participant( $product_id, $order->get_user_id(), $ticketnumber, $order_id, $item );
}

ОБНОВЛЕНО

Я создал таблицу для всех номеров билетов, которые будут сохранены в столбце «используется», как вы предложили. Затем я использую функцию запроса $ wpdb-> в операторе foreach и обновляю таблицу.

Однако я не уверен, как сгенерировать случайное число, которое будет использоваться в WHERE ticket_number = $ randomnumber ', и чтобы оно было уникальным, чтобы один клиент, заказавший 5 билетов, имел 5 разных номеров. Имеет ли это смысл?

add_action( 'woocommerce_order_status_processing', 'ektgn_meta_to_line_item', 20, 4 );

function ektgn_meta_to_line_item( $order_id )
{

    $order = wc_get_order($order_id);

    foreach( $order->get_items() as $item_id => $item_product ) {
        global $wpdb;

        $product_id = $item_product->get_product_id();
        $qty = get_field('maximum_entries', $product_id, true);
        $ticketOptions = range(1, $qty);
        $ticketAllocated = array_rand($ticketOptions, 1);

        $wpdb->query(
            "
            UPDATE wp_tickets 
            SET used = 1
            WHERE ticket_number= ".$ticketAllocated." AND lottery_id = ".$product_id." AND used = 0
            "
);     

}             

}

1 Ответ

0 голосов
/ 15 января 2019

Достаточно справедливо, если у вас есть только несколько заказов в день, но Amazon определенно получит несколько дублированных билетов таким образом. То, что вы ищете, это атомарная операция .

Возможные пути:

  • Создайте таблицу mysql с уникальным столбцом для номера билета. Поскольку вы не можете вставить число дважды ... выполните {INSERT INTO tickets ($ random_number)} при ошибке дубликата ключа

  • Создать таблицу mysql со всеми тикетами и столбцом флага «used» ... do {UPDATE tickets SET SET used = 1 WHERE ticket_number = $ random_number and used = 0; } while disabled_rows == 0;

  • Использовать повторный набор ... do {SADD tickets $ random_number}, в то время как результат == 0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...