ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql-select…中的最新行不可用以进行更新

2019-11-22 01:16:10  阅读:258  来源: 互联网

标签:dbi mysql perl


我在运行正在执行涉及两个表Users和Transactions的事务的Web服务时遇到问题.问题在于,当我从“事务”中选择时,有时无法找到最新行,而我可以看到该行存在于数据库中.

我使用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.例如,如果“交易”表中有87行,则返回84.

我不确定是否处理不正确.我使用select …保护更新更新的用户表,但是我没有使用Transactions表保护它.我不确定这是否重要.由于我将更新嵌套在用于对Users表进行更新的select …中的Transactions表中,因此我认为它将在事务中受到保护.

感谢有关事务表中的选择为何不返回最新行的任何帮助.

解决方法:

此问题通常是由InnoDB的默认隔离级别(“可重复读取”)引起的.这意味着在启动当前事务之后,连接看不到任何添加到数据库的内容.

您可以通过更改隔离级别(可能是Oracle的默认设置为“读取已提交”)或在选择开始新事务之前进行一次提交来避免此问题.

标签:dbi,mysql,perl
来源: https://codeday.me/bug/20191122/2055906.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有