你好,
我目前正在尝试运行一个处理apx~50k记录的存储过程。它将记录分类到不同的表中,删除一些记录等。
但是,相对较长的预备语句将始终导致以下错误:
> [2016-12-08 19:28:24] local.INFO: PDOException: SQLSTATE[HY000]:
> General error: 20003 Adaptive Server connection timed out [20003]
> (severity 6) [(null)] in
> /vendor/laravel/framework/src/Illuminate/Database/Connection.php:479
> Stack trace:
> #0 /vendor/laravel/framework/src/Illuminate/Database/Connection.php(479):
> PDOStatement->execute()
> #1 /vendor/laravel/framework/src/Illuminate/Database/Connection.php(762):
> Illuminate\Database\Connection->Illuminate\Database\{closure}(Object(Illuminate\Database\SqlServerConnection),
> 'EXEC dbo.cleanD...', Array)
> #2 /vendor/laravel/framework/src/Illuminate/Database/Connection.php(725):
> Illuminate\Database\Connection->runQueryCallback('EXEC dbo.cleanD...',
> Array, Object(Closure))
> #3 /vendor/laravel/framework/src/Illuminate/Database/Connection.php(480):
> Illuminate\Database\Connection->run('EXEC dbo.cleanD...', Array,
> Object(Closure))
> #4 /vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(317):
> Illuminate\Database\Connection->statement('EXEC dbo.cleanD...')
> #5 /vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(237):
> Illuminate\Database\DatabaseManager->__call('statement', Array)
让我感到震惊的是,通过使用laravel chunk,我可以插入~50k记录而不会发生任何事故:
$data = $data->chunk(500);
foreach ($data as $rows) {
Log::info("INSERT START: " . date('l jS \of F Y h:i:s A'));
DB::table("the.db")->insert($rows->toArray());
}
但是一旦存储过程运行(可能需要约2-4分钟)
我收到上述错误。我尝试了很多不同的解决方案,包括将存储过程分解为更小的解决方案,但我仍然得到了错误。
总是一样的错误:
General error: 20003 Adaptive Server connection timed out [20003] (severity 6) [(null)] in /vendor/laravel/framework/src/Illuminate/Database/Connection.php:479
我有一个潜行的怀疑,某个地方(在laravel?php.ini?),我可能不得不提高数据库的超时限制
任何事情都有帮助,提前谢谢!
答案 0 :(得分:3)
我无法验证这是否有效,但我在另一个问题中看到您使用选项PDO::ATTR_TIMEOUT
来强制设置更高的超时。我不确定默认是什么。
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'options' => [
PDO::ATTR_TIMEOUT => 240 // 240 seconds.
]
],
您可能还想查看Can I set a query timeout when using Zend_Db_Adapter_Pdo_Mssql?。
答案 1 :(得分:1)
除了@ user3158900提供的解决方案之外,我知道我在评论中提到了这一点,但只是在这里重申它们(因为评论可能会被删除),如果查询,你可能会考虑使用SQL Server Job不能再分解了。除了运行SQL脚本之外,作业还可以执行各种操作(集成包,命令行应用程序,脚本等),因此它们非常适合自动执行日常管理类型的任务。
如果您正在离开SQL Server,Oracle也有job scheduler,但我并不熟悉它。
由于您表示您计划在某个时候将逻辑移出SQL Server,一旦您有时间可能(如果您碰巧使用的是Windows服务器,我强烈推荐这一点,因为我拥有Microsoft stock :))是编写一个控制台应用程序并使用Windows Task Scheduler按照您选择的计划运行它。您甚至可以在后台运行它而无需打开控制台窗口。