在我的代码中,我使用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获取这些内容的全部细节。
答案 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并自己管理数据库连接,以便直接控制何时创建新连接。