Как реализовать транзакцию множественной проверки NULL в mysql

Я хочу реализовать логику проверки NULL в MYSQL. Вот код:

mysql> create table temp
(
id int,
des varchar(100),
primary key (id)
);

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

mysql> start transcation;

mysql> select * from temp where id=0;
Empty set (0.03 sec)

mysql> insert temp (id,des) values(0,'0');
Query OK, 1 row affected (0.11 sec)

mysql> commit;
Query OK, 0 rows affected (0.02 sec)

Вроде хорошо.

Тем не менее, в моей ситуации существует возможность выполнения нескольких транзакций с проверкой NULL одновременно.

Trans 1:                                             Trans 2:

mysql> start transaction;                            mysql> start transaction;         

mysql> select * from temp where id=0;
Empty set (0.03 sec)

                                                    mysql> select * from temp where id=0;
                                                    Empty set (0.03 sec)

mysql> insert temp (id,des) values(0,'0');
Query OK, 1 row affected (0.11 sec)

                                                    mysql> insert temp (id,des) values(0,'0');


mysql> commit;
Query OK, 0 rows affected (0.02 sec)

                                                    --block and waiting for the Trans 1 commit;
                                                    ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

Trans 2 сообщит об ОШИБКЕ 1062, когда Trans 1 зафиксирует. Я хочу избежать ошибки и считаю, что это универсальное явление проверки NULL в приложении.

Как правильно реализовать транзакцию множественной проверки NULL в mysql? Есть ли способы блокировать друг друга при использовании "select" sql в множественном переводе?

Спасибо.

обновление 2016.07.12

Я просто упрощаю ситуацию, с которой сталкиваюсь выше. На самом деле таблица у меня похожа на

mysql> create table temp
(
id int NOT NULL AUTO_INCREMENT,
des varchar(100),
unique_id int,
primary key (id),
UNIQUE (unique_id)
);

И мои транзакции

Trans 1:                                            Trans 2:

mysql> start transaction;                           mysql> start transaction;         

mysql> select * from temp where unique_id=0;
Empty set (0.06 sec)

                                                    mysql> select * from temp where unique_id=0;
                                                    Empty set (0.02 sec)

mysql> insert temp(des,unique_id) values('0',0);
Query OK, 1 row affected (0.20 sec)

                                                    mysql> insert temp(des,unique_id) values('0',0);


mysql> commit;
Query OK, 0 rows affected (0.02 sec)

                                                    --block and waiting for the Trans 1 commit;
                                                    ERROR 1062 (23000): Duplicate entry '0' for key 'unique_id'

Таким образом, ПЕРВИЧНЫЙ КЛЮЧ - AUTO_INCREMENT в моем реальном случае.

1 ответ

Если вы настаиваете на том, чтобы вставлять первичный ключ самостоятельно, а не в автоинкремент, то это именно то ожидаемое и желаемое поведение, для которого были созданы транзакции.

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

Другие вопросы по тегам