我在php中启用了线程,这样我就可以在同一时间做多个任务,目标是从Oracle服务器(12C)中提取数据到我的本地。
为什么要用线程?因为在某些时候,我们需要在几个表之间处理大约5亿条记录,所以我想在同一时间提取数据,以尽量减少处理时间。
这是我的php代码。
<?php
//*************Thread 1
class table1Class extends Thread{
public $bdconn;
public function __construct($bdconn) {
$this->bdconn = $bdconn;
}
public function run(){
$stTable1 = oci_parse($this->bdconn, 'INSERT INTO TABLE_1
SELECT * FROM TABLE_1@DBLINK');
oci_execute($stTable1); //******* LINE 13
}
}
//***********Thread 2
class table2Class extends Thread{
public $bdconn;
public function __construct($bdconn) {
$this->bdconn = $bdconn;
}
public function run(){
$stTable2 = oci_parse($this->bdconn, 'INSERT INTO TABLE_2
SELECT * FROM TABLE_2@DBLINK');
oci_execute($stTable2); //****** LINE 27
}
}
function pad($val) {
return ($val > 9) ? $val : "0".$val;
}
$start= microtime(true); //time
require_once '../../lib/bd_con.php';
$bdconn= conBd(); //open connection
/**********TRUNCATE LOCAL TABLES*/
$trunPref= oci_parse($bdconn, 'TRUNCATE TABLE TABLE_1');
oci_execute($trunPref);
$trunCruz= oci_parse($bdconn, 'TRUNCATE TABLE TABLE_2');
oci_execute($trunCruz);
/************END*/
//***********BEGIN THREADS
$table1 = new table1Class($bdconn);
$table1->start();
$table2 = new table2Class($bdconn);
$table2->start();
//*********WAINT FOR THREADS TO END
$table1->join();
$table2->join();
oci_close($bdconn); //close connection
//PRINT TIME INFORMATION
$end= microtime(true); //al final del archivo
$tiempo_segundos = number_format($end-$start,4);
echo pad(((Int)($tiempo_segundos/60))).":".pad(((Int)($tiempo_segundos%60)))." minutes";
这是我在执行过程中出现的错误:
警告: oci_execute(): ORA-01013: user requested cancel of currentoperation in C:\xampp\htdocs...\file.php on line 13
警告: oci_execute(): ORA-03117: two-task save area overflow inC:\xampp\htdocs...\file.php on line 27
小编解释一下这段代码要做的事情是:截断我的本地表,然后执行两个线程,用dblink从oracle server重新插入数据。
如果有人能给我一个解决这个问题的方法,我会很感激。
我有同样的错误,但在python中。显然,当两个不同的线程共享同一个oracle连接时,就会产生这个错误。
我所说的 "相同 "指的是完全相同的连接对象:如果你打开两个不同的连接(尽管他们有相同的用户和密码),就不会有任何问题。
为了避免这个问题 每个线程只用一个连接对象:你也可以使用连接池来实现这一点。