Понимание InnoDB X-Lock с уровнями изоляции REPEATABLE_READ и READ_COMMITED - PullRequest
1 голос
/ 12 июля 2020

У меня есть две таблицы mysql (AWS Aurora) db:

--------------------------------
|     Table:deparment          |
--------------------------------
--------------------------------
|    id      |  dept_name      |
--------------------------------
|     d1     |       dept1     |
--------------------------------
|     d2     |       dept2     |
--------------------------------
--------------------------------

-------------------------------------------------
|                Table:employee                 |
-------------------------------------------------
-------------------------------------------------
|   id      |   emp_name       |    dept_id     |
-------------------------------------------------
|   e1      |   Emp 1          |    d1          |
-------------------------------------------------
|   e2      |   Emp 2          |    d1          |
-------------------------------------------------
|   e3      |   Emp 3          |    d1          |
-------------------------------------------------
|   e4      |   Emp 4          |    d2          |
-------------------------------------------------

Business logi c: несколько потоков могут выполнять операции создания / изменения или удаления в таблицах Depatment и Employee. Любое изменение в таблице сотрудников приведет к обновлению идентификатора сотрудника

------
Java Code with Spring Transaction:

/**
*   Modify Employee
*/
@Transactional(isolation = REPEATABLE_READ)
public void modifyEmployeeByDeptarment(int deptId, int empId Update upd) {
    Department dept = deptDB.getDeparmentForUpdate(deptId); // returns SELECT * FROM department where id = :deptId FOR UPDATE; Row level Lock on dept
    
    Employee employee = empDB.getEmployee(deptId, employee.id); // returns SELECT * from employee where dept_id = :deptId;
    
    employee.setId(newEmpId);
    addUpdate(employee, upd); // This will update in DB
}

/**
*   Delete department with employees
*/
@Transactional(isolation = REPEATABLE_READ)
public void deleteDepartment(int deptId) {
    Department dept = deptDB.getDeparmentForUpdate(deptId); // returns SELECT * FROM department where id = :deptId FOR UPDATE; Row level Lock on dept

    List<Employee> employees = empDB.getEmployeesByDept(deptId); // returns SELECT * from employee where dept_id = :depltId;

    deleteDepartment(dept); // Deletes dept from DB
    deleteEmployees(employees); // Delete all employee for deptId
}
------

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

Кто-нибудь может объяснить это поведение?

Версия Spring Framework : 5.2.0.RELEASE Aurora MySQL Версия: 5.7.12

* Note: I changed the isolation level to READ_COMMITED, and everything was working as expected.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...