標籤:
當前在開發ERP系統,使用到的資料庫為Mysql。下面介紹下如何開啟事務,以及事務隔離的機制 :
1. 檢查當前資料庫使用的儲存引擎。
show engines;
2. 修改前my.ini中的檔案如下:
3. 修改my.ini的檔案如下。
3.1 修改了預設的儲存引擎
3.2 增加了mysql資料庫的交易隔離等級, 如果不添加預設是REPEATABLE-READ.
4. 只需要重啟mysql的服務即可。
net stop mysql
net start mysql
5. 重新查詢show engines,顯示如下
6. 事務隔離機制的說明,以下引用自別人的文章
- 未提交讀(READ UNCOMMITTED)。另一個事務修改了資料,但尚未提交,而本事務中的SELECT會讀到這些未被提交的資料(髒讀)。
- 提交讀(READ COMMITTED)。本事務讀取到的是最新的資料(其他事務提交後的)。問題是,在同一個事務裡,前後兩次相同的SELECT會讀到不同的結果(不重複讀)。如兩個會話a和b,由於是read committed所以只有當事務提交後才能被別的事務可見,當a執行查詢後b執行插入,b執行commit提交事務,這時a重新查詢結果確實不一樣的,a的兩次查詢同屬於一個事務,即為不可重複讀取。
- 可重複讀(REPEATABLE READ)。在同一個事務裡,SELECT的結果是事務開始時時間點的狀態,因此,同樣的SELECT操作讀到的結果會是一致的。直到提交事務後再查詢才可以看到其他事務在本事務執行期間鎖進行的更改操作。在MySQL中InnoDB和XtraDB儲存引擎通過多版本並發控制(MVCC)解決了幻讀的問題。
- 序列化(SERIALIZABLE)。讀操作會隱式擷取共用鎖定,可以保證不同事務間的互斥。
- SQL 交易隔離等級
在MySQL中預設交易隔離等級是可重複讀(Repeatable read).可通過SQL語句查詢:
查看InnoDB系統層級的交易隔離等級:mysql> SELECT @@global.tx_isolation; 在MySQL中預設交易隔離等級是可重複讀(Repeatable read).可通過SQL語句查詢:查看InnoDB系統層級的交易隔離等級: mysql> SELECT @@global.tx_isolation; 結果:+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec) 查看InnoDB會話層級的交易隔離等級: mysql> SELECT @@tx_isolation; 結果:
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec) 修改交易隔離等級:
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec) InnoDB 的可重複讀隔離等級和其他資料庫的可重複讀是有區別的,不會造成幻象讀(phantom read),所謂幻象讀,就是同一個事務內,多次select,可以讀取到其他session insert並已經commit的資料。下面是一個小的測試,證明InnoDB的可重複讀隔離等級不會造成幻象讀。測試涉及兩個session,分別為 session 1和session 2,隔離等級都是repeateable read,關閉autocommit mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec) session 1 建立表並插入測試資料
mysql> create table test(i int) engine=innodb; Query OK, 0 rows affected (0.00 sec)
mysql> insert into test values(1);
Query OK, 1 row affected (0.00 sec) session 2 查詢,沒有資料,正常,session1沒有提交,不允許髒讀
mysql> select * from test;
Empty set (0.00 sec) session 1 提交事務
mysql> commit;
Query OK, 0 rows affected (0.00 sec) session 2 查詢,還是沒有資料,沒有產生幻象讀
mysql> select * from test;
Empty set (0.00 sec)
當session2提交事務後才可以看到session1的插入資料;
以上實驗版本:
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 5.0.37-community-nt-log |
+-------------------------+
1 row in set (0.00 sec)
MySQL資料庫的交易管理