[英]Execute more than one statement at once in JDBC
我正在使用MySQL數據庫。 下一段創建一條記錄,並從創建的記錄中獲取ID:
insertStmt = connection
.prepareStatement("INSERT INTO bugs (summary, status, report_date) VALUES (?, ?, ? )");
//...
insertStmt.executeUpdate();
idQuery = connection.prepareStatement("SELECT LAST_INSERT_ID()");
rs = idQuery.executeQuery();
if (rs != null) {
rs.next();
return new Long(rs.getLong(1)).toString();
}
現在,如果有兩個線程執行此操作並交錯執行,例如,第一個線程插入記錄,然后由第二個線程插入,之后第一個線程調用last_insert_id(),此線程對於第二個線程而言是錯誤的已經插入了一條記錄。
但是,使用同步可以解決此問題。 有沒有辦法可以在一個數據庫調用中執行兩個語句?
LAST_INSERT_ID
每個連接有效,並且如您的問題所述,如果兩個線程中的兩個語句使用相同的連接,則可以具有競爭條件。
您有兩種解決方法:
1:每個線程使用單獨的連接(這並不容易,但這實際上是擴展和感知的最佳選擇;使用連接池)
2:使用executeUpdate
的形式在同一API調用中記錄自動生成的密鑰 ,使您以后可以使用getGeneratedKeys
讀取它,這樣就不必在第二個查詢中使用LAST_INSERT_ID
,從而避免了競爭情況。 您可以在准備好的語句中使用類似的prepareStatement
形式。
選擇2可能是短期內您想要的。 選項2中的鏈接直接指向該API。 此鏈接是MySQL文章,概述了如何使用它。
根據https://dev.mysql.com/doc/refman/5.7/zh-CN/connector-j-reference-configuration-properties.html ,您應該能夠在JDBC連接字符串中添加?allowMultiQueries=true
。 這樣,您就可以在Statement#execute(String sql)
調用中傳遞多個由分號分隔的Statement#execute(String sql)
。
編輯:或使用執行所需操作的存儲過程。 或者,正如您所說, synchronize
Java代碼。
您可以嘗試使用Multiquery,將Insert和Select Last_INSERT_ID()組合在同一字符串中。
1)准備使用多重查詢的連接:“ jdbc:mysql://” + host +“ /” + database +“?allowMultiQueries = true”
2)將插入查詢與選擇結合起來:
multiQuerySqlString =“將錯誤(摘要,狀態,報告日期)插入VALUES(1、2、3); SELECT LAST_INSERT_ID()”
3)進行查詢並期望有多個結果集:
boolean isResultSet = statement.execute();
ResultSet res = statement.getResultSet();
if isResultSet = statement.getMoreResults();
// Second ReulstSet object
res = cs.getResultSet();
我希望它能起作用
如果必須在單個連接上完成所有操作,則可以要求驅動程序返回生成的ID:
insertStmt = connection.prepareStatement("...",PreparedStatement.RETURN_GENERATED_KEYS );
insertStmt.executeUpdate();
ResultSet rs = insertStatement.getGeneratedKeys();
Long id = null;
if (rs != null)
{
rs.next();
id = rs.getLong(1);
}
connection.commit();
return id;
根據驅動程序,您可能需要一個不同的prepareStatement()
調用,該調用將列名作為第二個參數:
insertStmt = connection.prepareStatement("INSERT ", new String[] {"ID"});
但是即使使用上面的代碼,您也應該在不同的物理連接上進行並發插入,以便能夠正確地控制您的事務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.