我在php中启用了Threads,这样我就可以同时执行多个任务,目标是将数据从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:用户请求取消当前C:''examplep''htdocs中的操作。。。''第13行的file.php
警告:oci_execute():ORA-03117:中的两个任务存储区溢出C: ''axamp''htdocs。。。''第27行的file.php
关于代码的用途,一个小的解释是:截断我的本地表,并执行两个线程,使用dblink再次从oracle服务器插入数据。
如果有人能告诉我如何解决这个问题,我将不胜感激。
我在python中也遇到了同样的错误。显然,它是在两个不同的线程共享同一个oracle连接时产生的。
我所说的"相同"指的是完全相同的连接对象:如果你打开两个不同的连接(尽管它们有相同的用户和密码),就不会有任何问题。
为了避免这个问题每个线程只使用一个连接对象:您也可以使用连接池来实现这一点。