Perl5 DBI Mysql:获取last_insert_id的可靠方法

时间:2017-08-18 20:22:08

标签: mysql perl dbi dancer

在我的代码中,我使用database->last_insert_id(undef,undef,undef,"id");来获取自动增量主键。这有99.99%的时间。但偶尔会返回0值。 在这种情况下,使用类似于INSERT语句的值的WHERE子句运行select会显示插入成功。指示last_insert_id方法无法获取正确的数据。

这是已知修复的已知问题吗?或者我应该跟踪对last_insert_id的每次调用,检查它是否为零,如果是,则使用select语句来检索正确的ID值?

我的mysql版本是 mysql Ver 14.14 Distrib 5.7.19,适用于Linux(x86_64)

Edit1:添加实际的失败代码。

use Dancer2::Plugin::Database;
<Rest of the code to create the insert parameter>
eval{
     database->quick_insert("build",$job);
     $job->{idbuild}=database->last_insert_id(undef,undef,undef,"idbuild");
     if ($job->{idbuild}==0){
        my $build=database->quick_select("build",$job);
        $job->{idbuild}=$build->{idbuild};
        }
     };
debug ("=================Scheduler build Insert=======================*** ERROR :Got Error",$@) if $@;

注意:我正在使用Dancer的数据库插件。谁的描述说,

  

提供了一种获取连接的DBI数据库句柄的简便方法   只需在Dancer2应用程序中调用数据库关键字

     

返回一个Dancer :: Plugin :: Database :: Core :: Handle对象,它是一个   DBI的DBI :: db连接句柄对象的子类,所以它确实如此   你期望用DBI做的一切,但也增加了一些   便利方法。请参阅文档   Dancer :: Plugin :: Database :: Core :: Handle获取这些内容的全部细节。

1 个答案:

答案 0 :(得分:0)

我之前从未听说过这类问题,但我怀疑你的结束语可能是关键。 Dancer :: Plugin :: Database在幕后透明地管理数据库句柄。这可能非常方便......但这也意味着您可以随时使用一个dbh更改为使用不同的dbh。来自the docs

  

调用database将返回连接的数据库句柄;第一次调用它时,插件将建立与数据库的连接,并返回对DBI对象的引用。在后续调用中,将返回相同的DBI连接对象,除非发现它已不再可用(连接已消失),在这种情况下将获得新连接。

(强调我的)

而且,正如ysth在你的问题评论中指出的那样,last_insert_id是特定于句柄的,这表明,当你得到0时,这可能是由于句柄改变了你。

但是有希望!继续在D :: P :: DB文档中,有一个database_connection_lost挂钩可用,当数据库连接消失并且接收到作为参数的失效句柄时,将调用该挂钩,这将允许您检查和记录{钩子的回调子中的{1}}。这可以为您提供一种无需额外查询即可获取ID的方法,尽管您首先必须找到一种方法,将回调中的信息提供给主处理代码。

当然,另一个可能的解决方案是不使用D :: P :: DB并自己管理数据库连接,以便直接控制何时创建新连接。