[英]nodejs/postgresql on openshift: Failed to execute: 'control restart'
[英]Restart a failed transaction in PostgreSQL
通過事務,我的意思是在begin isolation level serializable
塊中包含(例如)幾個SQL語句。 並發事務可以使此事務失敗,即回滾。
如何在PostgreSQL中重啟失敗的事務?
您需要使用特定於客戶端驅動程序的機制來檢測事務中的錯誤。 當您看到錯誤時,您必須回滾事務並重新發出整個事務 。 你不能只重新做最新的第1部分。
ROLLBACK
是必需的; 如果不這樣做,該連接上的任何進一步操作都會因“事務中止”錯誤而失敗。
大多數客戶端驅動程序拋出異常(使用支持它們的語言)來指示SQL錯誤,或者希望您在每次數據庫操作后檢查錯誤代碼,方法是檢查函數返回代碼,或者調用特殊函數來檢查錯誤。 node-postgres
是異步和非阻塞的,因此它不太可能拋出異常; 您應該查找一個函數,該函數允許您查詢會話以查找最后一個操作導致的SQLSTATE
和客戶端驅動程序錯誤狀態。
node-postgres
似乎沒有豐富的文檔,所以你最好的選擇是檢查node-postgres的源代碼,或找到其他人如何做到這一點的例子。 我希望你能找到檢查會話錯誤狀態的函數。 您正在尋找的是為連接上的最后一個操作獲取SQLSTATE
的函數。
可能值得發布一個專門針對如何檢測和處理node-postgres中的錯誤的問題。
1實際上, SAVEPOINT
和ROLLBACK TO SAVEPOINT
讓你做到這一點,但它們無法幫助解決序列化錯誤。
這個答案在3年后被添加,以說明自那以來的變化。 盡管最初的答案仍然有效,但這個答案表明,今天使用當時無法使用的正確工具是多么容易。
使用pg-promise很容易,它支持任何嵌套級別的嵌套事務。 請參閱嵌套事務 ,其中解釋了當頂級事務由標准BEGIN
- > COMMIT
/ ROLLBACK
,所有嵌套事務都自動變為SAVEPOINT
。
db.tx(t => {
// BEGIN
// top-level changes cannot be restarted:
return t.any('UPDATE users SET name=$1 WHERE id=$2', ['Mike', 123])
.then(() => {
return t.tx(t1 => {
// SAVEPOINT
return t1.none('INSERT log(event) VALUES($1)', 'entry');
})
.catch(error => {
// ROLLBACK TO SAVEPOINT executed
return t.none('UPDATE log SET event = $1');
});
});
})
.then(data => {
// success, COMMIT executed
})
.catch(error => {
// error, ROLLBACK executed
});
在上面的示例中,我們在頂層執行UPDATE
,由於這個原因無法重新啟動。 然后我們使用INSERT
執行嵌套事務/保存點,如果失敗,則再次替換為頂層的UPDATE
。
這樣,即使我們的SAVEPOINT
失敗,我們仍然可以成功完成頂級交易。
如果您希望能夠重新啟動整個事務,只需將整個事務包裝到子事務中,然后可以根據需要在主事務內重新運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.