我有一個問題,我正在運行一個Web服務,執行涉及兩個表Users
和Transactions
的交易。麻煩的是,當我從Transactions
中選擇時,它有時無法找到我能夠看到的最新行,它存在於數據庫中。我使用Perl/Dancer作爲Web框架,但我認爲我遇到的問題是在數據庫級別(我使用的是MySQL/InnoDB)。僞代碼如下所示:最新的行沒有在選擇...更新
my $dbh = DBI->connect_cached(("DBI:mysql:Database;host=localhost;mysql_ssl=1",
"user", "password",
{RaiseError => 0, AutoCommit => 0});
my $sth_transact = $dbh->prepare("select balance from Users ".
"where id=? for update");
... store result in local variable ...
my $sth_inner = $dbh->prepare("select deposit from Transactions ".
"where id=?");
$sth_inner->execute();
if (my $deposit = $sth_inner->fetch_row()) {
$deposit *= $bonus;
$sth_inner = $dbh->prepare("update Transactions set deposit=?".
"where id=?");
$sth_inner->bind_param(1, $deposit);
$sth_inner->bind_param(2, $transaction_id);
$sth_inner->execute();
... update balance in Users table ...
}
在前面的幾請求選擇的交易表中返回最近的行。但是,在第三個請求中,它不能再找到最近的行。當我這樣做的時候:
my $sth_inner = $dbh->prepare("select id from Transactions where id=(SELECT max(id) from Transactions)");
它返回比最近行早3行的id。例如,如果Transactions
表中有87行,它將返回84.
我不確定我是否正確處理了鎖定。我使用select ... for update
鎖來保護Users
表,但我沒有爲Transactions
表執行此操作。我不確定這是否重要。由於我將更新嵌套在Users
表的select ... for update
中的Transactions
表中,我認爲它將在事務中受到保護。
爲什麼Transactions
表上的選擇沒有返回最近的行的任何幫助表示讚賞。
你能顯示你遺漏的代碼嗎? – ThisSuitIsBlackNot
它出現,如果我只是添加「...爲更新」的「從交易選擇存款」查詢它解決了問題。儘管我不確定我是否理解爲什麼會出現這種情況,爲什麼我需要在兩個表上鎖定。 –
添加了一些省略的代碼。主要的問題是它永遠不會輸入if語句,因爲給定id的行不可用(即使它在數據庫中)。 –