php线程出现oracle错误:两个任务保存区溢出。

问题描述 投票:1回答:1

我在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重新插入数据。

如果有人能给我一个解决这个问题的方法,我会很感激。

php multithreading oracle oracle12c
1个回答
0
投票

我有同样的错误,但在python中。显然,当两个不同的线程共享同一个oracle连接时,就会产生这个错误。

我所说的 "相同 "指的是完全相同的连接对象:如果你打开两个不同的连接(尽管他们有相同的用户和密码),就不会有任何问题。

为了避免这个问题 每个线程只用一个连接对象:你也可以使用连接池来实现这一点。

© www.soinside.com 2019 - 2024. All rights reserved.