[英]Non-blocking ODBC calls in Java
我使用了非常標准的Java ODBC功能-從池中獲取一個Connection
,創建一個Statement
並執行它。
我們的用例是一個游戲,記錄游戲進度-ODBC調用主要是對存儲過程的調用,並且在大多數情況下,沒有返回值。 因此,ODBC調用塊很煩人-游戲已經基於回合制,但是如果數據庫運行緩慢,用戶可以看到更長的暫停時間。
如果我不需要檢查ODBC調用的結果,是否有任何內置功能可以異步執行該語句? 如果不是,那么在不編寫大量代碼的情況下執行此操作的好方法是什么? 我仍然需要捕獲ODBC異常,只要它們發生就可以了。
盡管不完全相同,但這個問題看起來很相關... 可以進行異步jdbc調用嗎?
假設您有一個OdbcCaller
:
public class OdbcCaller {
public void callODBC() {
// call ODBC directly
// ...
}
您可以將其包裝在一個可運行的任務中,然后將該任務提交給線程池以使其異步執行:
public void asyncCallODBC() {
// wrap the call with a runnable task
executor.execute(new Runnable() {
@Override
public void run() {
callODBC();
}
});
// the above line would return immediately.
}
executor
是JDK提供的線程池實現,可以定義如下:
Executor executor = new ThreadPoolExecutor(/* core pool size */5,
/* maximum pool size */10,
/* keepAliveTime */1,
/* time unit of keepAliveTime */TimeUnit.MINUTES,
/* work queue */new ArrayBlockingQueue<Runnable>(10000),
/* custom thread factory */new ThreadFactory() {
private AtomicInteger counter = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "asyncCaller-" + (counter.incrementAndGet()));
return t;
}
},
/*
* policy applied when all tasks are occupied and task
* queue is full.
*/new ThreadPoolExecutor.CallerRunsPolicy());
ThreadPoolExecutor
是高度可配置的,並且在JavaDoc中有詳細記錄 ,您可能需要首先閱讀它。
以下是根據我的經驗提出的線程池配置的一些建議:
ThreadFactory
並為線程指定一個有意義的名稱。 當您需要檢查線程狀態(使用jstack
或其他工具)時,它將非常有用。 public class Snippet
{
static int i = 0;
public static void main(String[] args) throws SQLException
{
ExecutorService eventExecutor = Executors.newSingleThreadExecutor();
final Connection c = DriverManager.getConnection("jdbc:url", "user",
"password");
Runnable r = new Runnable()
{
public void run()
{
try
{
CallableStatement s = c
.prepareCall("{ call your_procedure(?) }");
s.setInt(1, i);
s.execute();
} catch (SQLException e)
{
e.printStackTrace();
}
}
};
for (; i < 100; i++)
eventExecutor.submit(r);
}
}
使用100個不同的參數將對your_procedure的調用運行100次。
如果使用的是EJB 3.1,則可以創建@Stateless
EJB,並標記方法之一@Asynchronous
。 這是企業Java環境一個徹頭徹尾的現成解決方案( 有外部管理Thread
資源不推薦)。
不確定,但是也許可以使用aynsctask? 在不同的線程中處理數據庫的東西
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.