Задача 1
Очень важным механизмом безопасности в финансовой транзакции является способность выполнять аудит.Нет никаких признаков того, что этот код оставляет какие-либо следы от бумаги.Нужно не только обновить баланс, но и создать запись транзакции.
Задача 2
Этот код страдает от состояния гонки.Подумайте, что произойдет, если это два одновременных действия.
Process 1 Process 2
=============================================== ===============================================
$xfer_amt = GetTransferAmount();
$balance = GetBalanceFromDatabase();
if ($xfer_amt < 0) {
FatalError("Bad Transfer Amount");
}
$xfer_amt = GetTransferAmount();
$balance = GetBalanceFromDatabase();
if ($xfer_amt < 0) {
FatalError("Bad Transfer Amount");
}
$newbalance = $balance - $xfer_amt;
if (($balance - $xfer_amt) < 0) {
FatalError("Insufficient Funds");
}
$newbalance = $balance - $xfer_amt;
if (($balance - $xfer_amt) < 0) {
FatalError("Insufficient Funds");
}
SendNewBalanceToDatabase($newbalance);
NotifyUser("Transfer of $xfer_amt succeeded.");
NotifyUser("New balance: $newbalance");
SendNewBalanceToDatabase($newbalance);
NotifyUser("Transfer of $xfer_amt succeeded.");
NotifyUser("New balance: $newbalance");
(Переименована переменная, чтобы код лучше отображался на экране.)
База данных будет вычтена только для одной из транзакций.
Выполнение этого права становится еще более сложным, поскольку вы включаете исправление для первой проблемы, потому что вам необходимо убедиться, что баланс всегда синхронизирован с записями транзакций (принимая во внимание возможность одновременных транзакций, сбоев сети, отключений электропитания и т. Д.).
Задача 3
Откуда взялись средства назад?В большинстве сценариев есть вероятность, что что-то сделать со снятыми средствами не удастся.Если это так, то вместо того, чтобы снимать средства, вам, вероятно, следует их зарезервировать (пометить их как недоступные) и снимать средства только после того, как они фактически были использованы.