MySQL - Sincronización de varios hilos

Hay una tarea: insertar N elementos en la tabla, pero antes de esto para determinar si dichos elementos ya se han agregado.

Es decir primero haciendo algo como:

SELECCIONAR CUENTA (*) DE xxx DÓNDE x ENTRADA (x1, x2, x3, x4, x5, x6 …… x1000);

Si el resultado es 0, puede hacer el mismo INSERT masivo.

Pero hay un problema: ¿cómo hacerlo con un subprocesamiento múltiple?

Es decir, digamos, cómo evitar una situación cuando se obtienen 2 hilos simultáneamente y el procedimiento es el siguiente:
P1: SELECCIONAR CUENTA (*) - obtiene "0"
P2: SELECT COUNT (*) - obtiene "0"
P1: inserta
A2: porque recibió un "cero" en la selección anterior, también hace que INSERTAR registros duplicados

¿Hay una solución para este problema?

La idea de exponer algún tipo de bandera global parece muy irónica y estúpida.

No ofrezco snaps, porque de nuevo - no salvarán de la simultaneidad. ¿Cómo se hacen tales cosas?

A veces se supone que se insertan archivos de datos grandes de varias decenas de miles, por lo que es probable que las consultas no se ejecuten muy rápidamente y que haya una posibilidad de detectar un error con la inserción simultánea.

PS: x - no es un campo único. Se muestra aquí por simplicidad. En realidad, verificar la posibilidad de agregar una entrada a la base de datos es mucho más complicado. - j
Respuestas
nathan deunk
Transacciones, innodb.
Pero no, la tontería dijo :) - alissa pryor
¿Y por qué tonterías? - samaneh karami
si x no es único (bueno, en general, no hay violaciones de integridad, etc.), entonces la segunda inserción no se elimina, pero normalmente duplica los registros; las transacciones no se guardarán aquí. - lindsy
Sí, con razón se dio cuenta. En principio, los bloqueos pueden ayudar, pero se eliminará el multihilo. - linda friedrich
lynsay
si x es un campo único, a continuación, agregue UNIQUE KEY. y especifique qué tipo de tabla tiene - myisam, innodb?
Acerca de "x" - agregó una pregunta.

Acerca de la tabla: aún no hemos elegido, pero tendemos, probablemente, a Innodb. - infinitexlibrary
ab commendatore
Una opción simple es LOCK TABLES, pero es mejor no abusar de los bloqueos.
¿A menos que "lok" localice la tabla para todas las conexiones paralelas? En algún lugar se vio que la tabla solo es actual, en lugar de ser global. - jim coughenour
Hay parámetros allí, si no me equivoco, con los que puede especificar cómo dividir la tabla - morag
sarah kate
BLOQUEAR TABLAS xxx ESCRIBIR;
SELECCIONAR CUENTA (*) DE xxx DÓNDE x ENTRADA (x1, x2, x3, x4, x5, x6 …… x1000);
...
Insertar en xxx ...;
TABLAS DE DESBLOQUEO;

Bloquea la mesa para otras sesiones. Si se utilizan otras tablas, por ejemplo, WHERE x IN (SELECT * FROM xxx1) para leer entre el bloqueo y el desbloqueo, también se deben usar si no se confunde con el bloqueo: LOCK TABLES xxx WRITE, xxx1 LEER
lauren love
ÍNDICE ÚNICO en todo el campo y hacer INSERT IGNORE . Los campos coincidentes se caen automáticamente, esta opción funcionará lo suficientemente rápido.
darcie
INSERTAR EN LA ACTUALIZACIÓN DUPLICADA y otros activadores de inserción.
también - BLOQUEAR tablas. También lok cerebros en el servidor y otros mutex.
Opción 3 - trabajar a través de una instalación intermedia