У меня есть 2 таблицы MySQL:
create table invoices
(
id bigint auto_increment primary key,
amount decimal(12, 2) default 0.00 not null,
amount_paid decimal(12, 2) default 0.00 not null,
amount_remaining decimal(12, 2) default 0.00 not null,
);
create table transactions
(
tx_id bigint auto_increment primary key,
amount decimal(12, 2) default 0.00 not null,
invoice_id biging default 0 not null,
constraint transactions_invoices_id_fk
foreign key (invoice_id) references invoices (id)
);
Как видите, транзакции относятся к счетам.Один счет может иметь несколько транзакций.У меня будет несколько процессов, обрабатывающих входящие транзакции, но говорящих с одной и той же БД.Интересно, какую изоляцию мне использовать, мне нужно SERIALIZABLE
?Что мне нужно сделать, это что-то вроде:
START TRANSACTION
SELECT * FROM transactions WHERE tx_id=T
if such transactions exists already abort execution
otherwise
SELECT * FROM invoices WHERE id = X (X is known to me prior to execution)
INSERT new transaction for invoice_id=X
UPDATE invoices SET amount_paid = amount_paid + Y, amount_remaining=amount_remaining-Y WHERE tx_id = T
COMMIT
Мои вопросы:
- Нужен ли мне SERIALIZABLE уровень изоляции транзакции?
- Должен ли
SELECT * FROM invoices
be FOR UPDATE
? - Будет ли
SERIALIZABLE
транзакция блокировать только отдельные строки таблицы invoices
(с id = X) - Будет
SERIALIZABLE
транзакция блокировать только отдельные строки transactions
таблица (с invoice_id = X)?Другими словами, достаточно ли умна блокировка, чтобы влиять только на транзакции на основе их внешнего ключа invoice_id?Так что я могу одновременно работать с разными счетами без проблем с блокировкой?
Спасибо всем за ответы!