Category: "MySQL, Oracle, 數據庫" , Tags: InnoDB, MyISAM, MySQL, Oracle, transaction, 事務
是Shacho寫著呢.
這幾次, 我一直推銷我們的產品, 所以呢, 現在講別的事情吧. 就是我開發DB Tracklayer的時候意識到的有點奇怪的事.
在MySQL上, MyIsam/InnoDB混合在一起的Transaction(事務)
這也是面向從Oracle切換到MySQL的人.
在Oracle(或者, 應該說‘一般’嗎?), 我們考慮Transaction(事務)這樣. 你要一個決定來處理一連的操作的時候, 你用Transaction(事務)處理進程然後Commit或者Rollback.
我覺得Transaction(事務)一般是這樣子.
現在我們不考慮Transaction levels和鎖定.
Transaction要明確的開始和結束, 從而你要留意的是有沒有不明確地結束transaction的事情. (我們現在不考慮levels和鎖定)
要是你不太明白什麼語句會不明確地結束transactions, 就寫像Truncate不明確地把transaction結束的東西, 結果很慘, 你到那裡寫的進程都會被Commit.
不過, 你理解這點就沒有什麼難用的. (記得嗎?我們現在不考慮levels和鎖定哦)
因為Oracle對Schema只有一種引擎, 我們可以像上述處理.
我覺得你在Oracle上操作的時候不會留意DB引擎或存儲引擎(或者只有我不知道的嗎?).
另一方面, 在MySQL, 你可以按表來設置存儲引擎, 這意味一個Schema(數據庫)可能會有幾種引擎混合在一起.
我覺得, Schema的物理設計應該按照引擎分開, 不過, 那種物理設計不一定存在.
那, 在transaction裡執行MyIsam/InnoDB混合在一起的進程的話, 會怎麼樣?嗯嗯嗯… 不能馬上回答…
唉, 太遺憾了!因此, 實驗看看吧.
單步執行以下語句的時候, 也有另一個session(會話)在瀏覽.
① create table test1 ( col1 int ) engine=InnoDB;
② create table test2 ( col1 int ) engine=MyISAM;
③ start transaction;
④ insert into test1 values (11);
⑤ insert into test2 values (21);
⑥ commit;
① mysql> create table test1 ( col1 int ) engine=InnoDB;
Query OK, 0 rows affected (0.05 sec)
mysql> show create table test1;
+——-+——————————————————————————————-+
| Table | Create Table |
+——-+——————————————————————————————-+
| test1 | CREATE TABLE `test1` (
`col1` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+——-+——————————————————————————————-+
1 row in set (0.00 sec)
② mysql> create table test2 ( col1 int ) engine=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> show create table test2;
+——-+——————————————————————————————-+
| Table | Create Table |
+——-+——————————————————————————————-+
| test2 | CREATE TABLE `test2` (
`col1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+——-+——————————————————————————————-+
1 row in set (0.00 sec)
③ mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
④ mysql> insert into test1 values (11);
Query OK, 1 row affected (0.01 sec)
・執行之後, 從同一個會話(session)確認一下
mysql> select * from test1;
+——+
| col1 |
+——+
| 11 |
+——+
1 row in set (0.00 sec)
・從另一個會話(session)確認一下
mysql> select * from test1;
Empty set (0.01 sec)
⑤ mysql> insert into test2 values (21);
Query OK, 1 row affected (0.00 sec)
・執行之後, 從同一個會話(session)確認一下
mysql> select * from test1;
+——+
| col1 |
+——+
| 11 |
+——+
1 row in set (0.00 sec)
mysql> select * from test2;
+——+
| col1 |
+——+
| 21 |
+——+
1 row in set (0.00 sec)
・從另一個會話(session)確認一下
mysql> select * from test1;
Empty set (0.00 sec)
mysql> select * from test2;
+——+
| col1 |
+——+
| 21 |
+——+
1 row in set (0.00 sec)
・從以上, 可以說InnoDB表還在transaction裡,
另一方面, 無論是否還在transaction裡, MyISAM表會自動地被commit (本來, 這概念本身不存在)
還有即使MyISAM表數據確定了, transaction仍然不會被commit或者中斷.
⑥ mysql> commit;
Query OK, 0 rows affected (0.04 sec)
・從同一個會話(session)確認一下
mysql> select * from test1;
+——+
| col1 |
+——+
| 11 |
+——+
1 row in set (0.00 sec)
mysql> select * from test2;
+——+
| col1 |
+——+
| 21 |
+——+
1 row in set (0.00 sec)
・從另一個會話(session)確認一下
mysql> select * from test1;
+——+
| col1 |
+——+
| 11 |
+——+
1 row in set (0.00 sec)
mysql> select * from test2;
+——+
| col1 |
+——+
| 21 |
+——+
1 row in set (0.00 sec)
・從以上, 可以理解在⑤transaction沒有受中斷.
・因此, 我的結論是;
・你不用擔心引擎混合在一起.
・向不支持transaction的引擎發行transaction是沒什麼意思的, 但也沒有什麼害的, 所以你不需要擔心 (你故意要那樣做也是自由的)
嗯, 跟我想像的差不多. 即使如此, 我沒有自信, 所以很好的機會實際看一看.
有機會, 我們考慮更本質的內容吧.
那, 今天到這裡吧.
再見!


