簡體   English   中英

如何在不使用事務的情況下使用JDBC / jTDS執行存儲過程?

[英]How can I execute a stored procedure with JDBC / jTDS without using a transaction?

我們運行一個用Java編寫的網站,該網站使用JDBC和jTDS來訪問SQL Server數據庫。

我們的數據庫包含一個復雜的存儲過程,通常需要10分鍾才能運行。 如果我們直接執行存儲過程(例如從SQL Server Management Studio中執行),則該存儲過程可以正常工作,因為它不在事務中運行。 但是,如果我們使用jTDS執行它,那么它將鎖定整個網站10分鍾。 發生這種情況是因為jTDS在事務中運行它,因此所有網站請求都處於等待狀態,以等待事務完成。

例如,以下內容因交易而鎖定了網站:

Connection connection = DriverManager.getConnection("jdbc:jtds:sqlserver://example/example");
CallableStatement callableStatement = connection.prepareCall("exec dbo.procTest");
callableStatement.execute();

有什么方法可以使我們使用JDBC / jTDS運行存儲過程而不在事務中運行存儲過程?

請注意,在jTDS連接上調用此命令無效:

connection.setTransactionIsolation(Connection.TRANSACTION_NONE);

拋出一個異常,表明jTDS不支持Connection.TRANSACTION_NONE參數。


編輯:我可能會問得更好:核心問題不是事務本身,問題是事務導致數據庫鎖定被保留10分鍾。 我需要擺脫交易 ,或者需要在交易期間釋放鎖

在我們的例子中,必須調用StoredProcedure,從jtds調用時拋出異常:

無法在事務內執行備份或還原操作。

我在@ https://communities.bmc.com/docs/DOC-66239上發現的是,exec調用必須以“ SET IMPLICIT_TRANSACTIONS OFF;”開頭。

這是基於春季的代碼段的樣子:

try {
  jdbcTemplate.getJdbcOperations.execute("SET IMPLICIT_TRANSACTIONS OFF;")
  //noinspection ConvertExpressionToSAM   // we have 1.6 code version
  jdbcTemplate.getJdbcOperations.call(new CallableStatementCreator {
    override def createCallableStatement(con: Connection): CallableStatement = {
      val callableStatement = con.prepareCall(
        s""" EXEC dbo.RestoreLatestCopy
           |      @ID = ?
           |""".stripMargin)
      callableStatement.setInt(1, getMappedRestoreId(fromDbName))
      callableStatement
    }
  }, parameters ++ rsParams)
} catch {

調用Connection#close()Connection#commit()應該提交並結束事務。 您是否在finally塊中關閉了數據庫資源(如Connection

我最終使用了以下丑陋的解決方法。 我仍然很感興趣是否有人可以解釋我如何正確執行此操作; 但是暫時可以解決。

該數據庫在Web服務器上的同一台計算機上運行,​​因此我可以使用標准的SQL Server命令行工具來運行存儲過程。 觸發它的Java代碼是:

    try {
        Process process = Runtime.getRuntime().exec("sqlcmd -E -d \"example\" -Q \"EXEC dbo.procTest;\"");
        process.waitFor();
    } catch (IOException e) {
        // Handler here
    } catch (InterruptedException e) {
        // Handler here
    }

因此,運行的存儲過程完全相同—區別在於Web服務器不會鎖定,因為sqlcmd不在單個事務中運行它。 是的,這很丑陋……但這是我所知道的唯一可行的選擇!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM