我可以在 MySQL 中模擬 Oracle 的自治事務嗎?
我有許多表,它們上面有觸發器,可以在排隊和日誌表中插入記錄。問題是這些插入是同一事務的一部分。這意味著以前表上的任何 IUD 都可以被觸發插入同一隊列的其他 IUD 鎖定,並且不會記錄失敗的 IUD,因為這些插入也會被回滾。
我不太關心觸發 IUD 回滾的隊列中的條目。隊列被一些使記憶體無效/刷新記憶體和類似操作的程序讀取。如果有任何內容被回滾,一些記憶體將使用相同的數據進行刷新。沒什麼大不了。
這裡的商業案例是一個網站,其中包含大量由單個產品組成的集合。任何一種產品最多可以有 15,000 套。如果產品的價格發生變化,則需要重新計算所有這些集合的價格。在保存產品價格時,我不想在同一事務中執行此操作,因為這會花費太多時間並鎖定太多數據庫,因此我將重新計算排入隊列。
對於日誌記錄,我想記錄一些操作,即使(尤其是)失敗。我現在不能那樣做。
如果是我直到最近才使用的這個 Oracle,我會習慣於
PRAGMA AUTONOMOUS_TRANSACTION
在單獨的事務中處理插入,無論其他事務做什麼,它總是會送出。我可以通過將 MyISAM 表用於日誌和隊列來模擬這種行為,
concurrent_insert
設置為ALWAYS
,而我的其餘表是 InnoDB?(我希望它們有多個插入,這就是整個問題,而它們很少被讀取(日誌),或者只有一次(隊列))。
如果您可以訪問 Aria 引擎或其他非事務性引擎,那麼可以。
非常簡短的概念證明,在 MariaDB 10.5.4 上進行了測試:
CREATE TABLE test_aria_engine ( a int, b varchar(1000) ) ENGINE=Aria DEFAULT CHARSET=utf8 PAGE_CHECKSUM=1 TRANSACTIONAL=1 TABLE_CHECKSUM=1 COMMENT='test-aria_engine with transactional on 1'
Aria 中的 transactional 不是真正的事務,它只是最後的操作日誌,在伺服器崩潰的情況下仍然很好,數據是一致的。
現在創建一個 InnoDB 表:
CREATE TABLE test_innodb_engine ( a int , b varchar(1000) )
並測試:
BEGIN TRANSACTION; -- insert in aria table INSERT INTO test_aria_engine ( a, b) VALUES (4 , 'ddd'); -- insert in innodb table INSERT INTO test_innodb_engine( a, b) VALUES ( 4 , 'dddd'); -- rollback ROLLBACK;
啟動 ROLLBACK 後,讓我們檢查 Aria 和 InnoDB 表的表內容:
SELECT * FROM test_aria_engine;
|a |b | |---|---| |4 |ddd|
所以,ROLLBACK 不能回滾 ARIA 引擎
SELECT * FROM test_innodb_table;
No result.
所以在 InnoDB 表中 ROLLBACK 已經完成了它的工作。
這顯示瞭如何避免 MariaDB 中的事務邏輯或在 MySQL 中使用類似的引擎,如 MyISAM。