sql >> Databáze >  >> RDS >> Mysql

Proč explicitní zamykání predikátu MySQL neumožňuje příkazy INSERT mimo predikátový zámek

SELECT FOR UPDATE se zamyká mezi 1 a další hodnotou v tabulce zaměstnanců. Protože neexistuje žádná další hodnota, zamyká se až do supremum pseudo-record . To lze vidět v information_schema.innodb_locks :

mysql> select * from innodb_locks;
+----------------+-------------+-----------+-----------+-------------------+------------+------------+-----------+----------+------------------------+
| lock_id        | lock_trx_id | lock_mode | lock_type | lock_table        | lock_index | lock_space | lock_page | lock_rec | lock_data              |
+----------------+-------------+-----------+-----------+-------------------+------------+------------+-----------+----------+------------------------+
| 28275:1448:3:1 | 28275       | X         | RECORD    | `test`.`employee` | PRIMARY    |       1448 |         3 |        1 | supremum pseudo-record |
| 28273:1448:3:1 | 28273       | X         | RECORD    | `test`.`employee` | PRIMARY    |       1448 |         3 |        1 | supremum pseudo-record |
+----------------+-------------+-----------+-----------+-------------------+------------+------------+-----------+----------+------------------------+
2 rows in set, 1 warning (0.00 sec)

Pokud mírně změníte testovací případ, aby byl v položkách zaměstnanci řádek pro dept-id=2, a poté zkusíte přidat zaměstnance pro dept-id=3, bude to fungovat. Příklad:

create table department (
    id bigint not null, 
    budget bigint not null, 
    name varchar(255), 
    primary key (id)
) ENGINE=InnoDB;

create table employee (
    id bigint not null, 
    name varchar(255), 
    salary bigint not null, 
    department_id bigint, primary key (id)
) ENGINE=InnoDB;


alter table employee 
add constraint FK_department_id 
foreign key (department_id) 
references department (id);


insert into department (name, budget, id) 
values ('Hypersistence', 100000, 1);

insert into department (name, budget, id) 
values ('Bitsystem', 10000, 2);

insert into department (name, budget, id) 
values ('XX', 10000, 3);


insert into employee (department_id, name, salary, id) 
values (1, 'John Doe 0', 30000, 0);

insert into employee (department_id, name, salary, id) 
values (1, 'John Doe 1', 30000, 1);

insert into employee (department_id, name, salary, id) 
values (2, 'John Doe 2', 30000, 2);


start transaction;

SELECT * 
FROM employee 
WHERE department_id = 1 
FOR UPDATE;


# new session

insert into employee (department_id, name, salary, id) 
values (3, 'Dave', 9000, 5)


  1. Numerické funkce v Oracle (úplný seznam)

  2. Chyba sql:Převod datového typu varchar na datový typ datetime vedl k hodnotě mimo rozsah

  3. Chyba SQLAlchemy bez zadání hesla

  4. AWS RDS:„SQLSTATE[22001] – Data jsou příliš dlouhá pro sloupec“ pomocí MariaDB 10.2