Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala尾部递归java.lang.StackOverflower错误_Scala_Tail Recursion - Fatal编程技术网

Scala尾部递归java.lang.StackOverflower错误

Scala尾部递归java.lang.StackOverflower错误,scala,tail-recursion,Scala,Tail Recursion,我正在迭代查询一个名为txqueue的mysql表,该表正在不断增长 每个后续查询只考虑在上一次迭代中执行查询之后插入到txqueue表中的行 为了实现这一点,每个后续查询都会从主键(以下示例中的seqno字段)超过上一个查询中观察到的最大seqno的表中选择行 以这种方式标识的任何新插入行都将写入csv文件 其目的是使该过程无限期地运行 下面的尾部递归函数工作正常,但过了一段时间后,它会运行到java.lang.StackOverflowerError中。每个迭代查询的结果包含两到三行,结果大

我正在迭代查询一个名为txqueue的mysql表,该表正在不断增长

每个后续查询只考虑在上一次迭代中执行查询之后插入到txqueue表中的行

为了实现这一点,每个后续查询都会从主键(以下示例中的seqno字段)超过上一个查询中观察到的最大seqno的表中选择行

以这种方式标识的任何新插入行都将写入csv文件

其目的是使该过程无限期地运行

下面的尾部递归函数工作正常,但过了一段时间后,它会运行到java.lang.StackOverflowerError中。每个迭代查询的结果包含两到三行,结果大约每秒返回一次

有没有关于如何避免java.lang.StackOverflower错误的想法

这实际上是流媒体可以/应该实现的吗

非常感谢你的建议

下面是一段时间内有效的代码:

object TXQImport {

  val driver = "com.mysql.jdbc.Driver"
  val url = "jdbc:mysql://mysqlserveraddress/mysqldb"
  val username = "username"
  val password = "password"
  var connection:Connection = null

  def txImportLoop(startID : BigDecimal) : Unit = {

      try {

        Class.forName(driver)
        connection = DriverManager.getConnection(url, username, password)
        val statement = connection.createStatement()
        val newMaxID = statement.executeQuery("SELECT max(seqno) as maxid from txqueue")

        val maxid = new Iterator[BigDecimal] {
          def hasNext = newMaxID.next()
          def next() = newMaxID.getBigDecimal(1)
        }.toStream.max

        val selectStatement = statement.executeQuery("SELECT seqno,someotherfield " +
          " from txqueue where seqno >= " + startID + " and seqno < " + maxid)

        if(startID != maxid) {

          val ts = System.currentTimeMillis
          val file = new java.io.File("F:\\txqueue " + ts + ".txt")
          val bw = new BufferedWriter(new FileWriter(file))

          // Iterate Over ResultSet
          while (selectStatement.next()) {

            bw.write(selectStatement.getString(1) + "," + selectStatement.getString(2))
            bw.newLine()

          }

          bw.close()

        }

        connection.close()
        txImportLoop(maxid)

      }

      catch {
        case e => e.printStackTrace
      }  

  }

  def main(args: Array[String]) {

    txImportLoop(0)

  }

}
对象TXQImport{
val driver=“com.mysql.jdbc.driver”
val url=“jdbc:mysql://mysqlserveraddress/mysqldb"
val username=“username”
val password=“password”
变量连接:连接=null
def txImportLoop(startID:BigDecimal):单位={
试一试{
Class.forName(驱动程序)
connection=DriverManager.getConnection(url、用户名、密码)
val语句=connection.createStatement()
val newMaxID=statement.executeQuery(“从txqueue中选择max(seqno)作为maxid”)
val maxid=新迭代器[BigDecimal]{
def hasNext=newMaxID.next()
def next()=newMaxID.getBigDecimal(1)
}.toStream.max
val selectStatement=statement.executeQuery(“选择seqno,someotherfield”+
“来自txqueue,其中seqno>=”+startID+“和seqno<”+maxid)
if(startID!=maxid){
val ts=System.currentTimeMillis
val file=new java.io.file(“F:\\txqueue”+ts+“.txt”)
val bw=新缓冲写入程序(新文件写入程序(文件))
//迭代结果集
while(selectStatement.next()){
write(selectStatement.getString(1)+“,“+selectStatement.getString(2))
bw.newLine()
}
bw.close()
}
连接。关闭()
txImportLoop(maxid)
}
抓住{
案例e=>e.printStackTrace
}  
}
def main(参数:数组[字符串]){
txImportLoop(0)
}
}

您的函数不是尾部递归函数(因为最后出现了
catch
)。 这就是为什么最终会出现堆栈溢出


您应该始终使用
@scala.annotation.tailrec
注释要进行尾部递归的函数-如果尾部递归不可能,它将无法编译,因此您在运行时不会对此感到惊讶。

您的函数不是尾部递归的(因为最后出现了
catch
)。 这就是为什么最终会出现堆栈溢出

您应该始终使用
@scala.annotation.tailrec
,对要进行尾部递归的函数进行注释-如果尾部递归不可能实现,则编译将失败,因此在运行时您不会对此感到惊讶