Transaction
如果我無法回滾交易,為什麼 Vertica 會讓我開始交易?
我對 Vertica 數據庫執行以下語句,一次一個:
BEGIN TRANSACTION; UPDATE table SET col1 = 'something' WHERE col2 = 'something else'; SELECT COUNT(*) FROM table WHERE col1 = 'something'; ROLLBACK TRANSACTION;
我執行第一行很好……好吧,現在我正在進行交易。
我執行我的更新……好吧,這工作。
我執行
SELECT
測試以確保事情按預期工作……哦,等等,看起來我錯過了語句WHERE
子句中的一個條件UPDATE
。不用擔心!這就是我在交易中這樣做的原因。
讓我們回滾:
=> ROLLBACK TRANSACTION; [Vertica][JDBC](10040) Cannot use commit while Connection is in auto-commit mode.
瓊斯,把你桌上的那卷衛生紙交出來。
所以 Vertica 很高興地接受了我的
BEGIN TRANSACTION
,因為我非常清楚,在那之後我會嘗試執行 aROLLBACK
或COMMIT
.然而,我做不到!我的連接處於自動送出模式,因此
ROLLBACK
毫無COMMIT
意義。我UPDATE
的承諾在它完成的那一刻。我錯過了什麼,還是我認為這只是 Vertica 的一個非常糟糕的實現?
如果邏輯結果 (或) 是非法的,為什麼 Vertica 會
BEGIN TRANSACTION
在自動送出模式下接受連接?ROLLBACK``COMMIT
Vertica 支持已確認此問題,並正在跟踪 VER-44735 下的修復。不幸的是,Vertica 問題跟踪器不公開可見。
Vertica 拒絕將此描述為錯誤,而是將其標記為“新功能請求”,但無論如何這應該在即將發布的版本中解決。
Vertica(實際上,我認為如果不是所有數據庫的話,大多數數據庫)都以這種方式執行,因為處理
BEGIN TRANSACTION
SQL 語句的部分,即查詢解析和執行引擎,不知道客戶端的 AUTOCOMMIT 設置。另一方面,客戶端不知道字元串“BEGIN TRANSACTION”的含義。
vsql
假設使用命令行客戶端執行範例,控制流看起來像這樣:
- 使用者啟動
vsql
並連接到數據庫。- 使用者輸入
\set AUTOCOMMIT on
。在那一刻之後,客戶端 ( ) 知道在每個成功的語句之後vsql
發出一個隱式語句。COMMIT
- 使用者輸入
BEGIN TRANSACTION
。vsql
不將該字元串辨識為其內部命令之一,並將該字元串發送到伺服器進行處理。- 伺服器將字元串辨識為有效的 SQL 語句,對其進行編譯,啟動事務,並將成功的結果程式碼返回給客戶端。由於自動送出是客戶端設置,伺服器對此一無所知。
- 客戶端收到成功的結果程式碼後,
COMMIT
向伺服器發出問題。- 伺服器遵守並送出它剛剛開始的事務。
等等。