mysql - escape_str - get_where codeigniter



Как получить последний идентификатор вставки mysql с транзакциями?+вопросы по сделке (1)

Чтобы ответить на ваш первый вопрос ...

При использовании транзакций ваши запросы выполняются обычно в зависимости от вашего подключения. Вы можете выбрать фиксацию, сохранение этих изменений или откат, возвращая все изменения. Рассмотрим следующий псевдокод:

insert into number(Random_number) values (rand()); 
select Random_number from number where Number_id=Last_insert_id();

// PHP

if($num < 1)
   $this->db->query('rollback;'); // This number is too depressing.
else
   $this->db->query('commit;'); // This number is just right.

Случайное число, которое было сгенерировано, можно прочитать перед фиксацией, чтобы убедиться, что оно подходит, прежде чем сохранять его для просмотра всеми (например, фиксация и разблокировка строки).

Если драйвер PDO не работает, рассмотрите возможность использования драйвера mysqli. Если это не вариант, вы всегда можете использовать запрос «select last_insert_id () как id; а не функцию $ this-> db-> insert_id ().

Чтобы ответить на второй вопрос, если вы вставляете или обновляете данные, которые другие модели будут обновлять или читать, обязательно используйте транзакции. Например, если столбец «Number_remaining» установлен в 1, может возникнуть следующая проблема.

Person A reads 1
Person B reads 1
Person A wins $1000!
Person A updates 1 to be 0
Person B wins $1000!
Person B updates 0 to be 0

Использование транзакций в одной и той же ситуации приведет к такому результату:

Лицо A начинает транзакцию
Лицо A читает «1» из Number_remaining
(Строка теперь заблокирована, если используется выбор для обновления )
Человек B пытается прочитать Number_remaining - вынужден ждать
Лицо A выигрывает 1000 долларов
Человек А обновляет 1, чтобы быть 0
Лицо А совершает
Лицо B читает 0
Человек B не выигрывает 1000 долларов
Лицо B плачет

Возможно, вам захочется прочитать уровни изоляции транзакций .

Будьте осторожны с тупиком, который может произойти в этом случае:

Лицо A читает строку 1 ( select ... for update )
Лицо B читает строку 2 ( select ... for update )
Человек A пытается прочитать строку 2, заставил ждать
Человек B пытается прочитать строку 1, вынужденную ждать
Лицо A достигает innodb_lock_wait_timeout (по умолчанию 50 секунд) и отключается
Лицо B читает строку 1 и продолжает нормально

В конце концов, поскольку Person B, вероятно, достигло max_execution_time PHP, текущий запрос завершит выполнение независимо от PHP, но дальнейшие запросы не будут получены. Если это была транзакция с autocommit = 0, запрос автоматически откатится, когда соединение с вашим сервером PHP будет разорвано.

Двухчастный вопрос:

  1. В моем сценарии CodeIgniter я начинаю транзакцию, а затем вставляю строку, устанавливая insert_id () в переменную php, вставляя больше строк в другую таблицу, используя новый идентификатор в качестве внешнего ключа, а затем выполняю все.

    Поэтому мой вопрос: если все не совершает транзакции до окончания транзакции, как mysql может вернуть последний идентификатор вставки, если ничего не было вставлено? Мой скрипт работает (почти) отлично, с новым ID, который используется в последующих запросах.

    (Я говорю «почти», потому что, используя драйвер PDO mysql, иногда первая вставка, которая должна возвращать insert_id (), дублируется - она ​​вставлена ​​дважды. Любая идея, почему это было? Связано ли это с получением последнего ID? Это никогда не происходит при использовании драйвера mysqli или mysql.)

  2. Я сначала написал сценарий без транзакций, поэтому у меня есть код, который проверяет ошибки mysql на этом пути, например:

    if(!$this->db->insert($table, $data)) {
        //log message here
    }
    

    Как это влияет на процесс mysql, как только я завернул весь мой код mysql в транзакции? Это не вызывает никаких видимых ошибок (надеюсь, не связанных с проблемой, о которой говорилось выше), но следует ли ее удалить?

Спасибо.





pdo