1. 程式人生 > >資料庫事務隔離級別測試-postgresql

資料庫事務隔離級別測試-postgresql

1. read-committed (default 級別)

客戶端A:
epmdb=> start transaction ;
START TRANSACTION
epmdb=> update t1.dbversion  set  value =1200  where dbversionid=1;
UPDATE 1
epmdb=> 


客戶端B:
epmdb=> start  transaction 
epmdb-> ;
START TRANSACTION
epmdb=> select * from t1.dbversion ;
 dbversionid | value  | currentdataversion | targetdataversion 
-------------+--------+--------------------+-------------------
           1 | 110000 |                100 |                 1
(1 row)

客戶端A修改後,結果不變:

epmdb=> select * from t1.dbversion ;
 dbversionid | value  | currentdataversion | targetdataversion 
-------------+--------+--------------------+-------------------
           1 | 110000 |                100 |                 1
A提交:
epmdb=> commit
epmdb-> ;
COMMIT


B查詢:
epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |  1200 |                100 |                 1
(1 row)

2.  read-uncommited(Postgresql 不支援)

修改隔離級別:修改後需要重新連線資料庫 否則級別不會更改,重新連線也不行,需要分別修改A B的事務隔離級別,或者修改預設的事務隔離級別
不是設定問題,經過查閱doc,postgresq 不支援此級別 epmdb=> start transaction ;
START TRANSACTION
epmdb=>  set default_transaction_isolation='read uncommitted';
SET
epmdb=> commit;
COMMIT
epmdb=> show default_transaction_isolation;
 default_transaction_isolation 
-------------------------------
 read uncommitted
(1 row)
epmdb=>  set default_transaction_isolation='read uncommitted';
SET
epmdb=> show default_transaction_isolation;
 default_transaction_isolation 
-------------------------------
 read uncommitted
(1 row)

開啟事務,查詢當前資料: epmdb=> start transaction ;
START TRANSACTION
epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |  1200 |                100 |                 1
(1 row)


epmdb=> 

3. repeatable-read

epmdb=> set default_transaction_isolation TO  'repeatable read'
;
SET
epmdb=> show default_transaction_isolation ;
 default_transaction_isolation 
-------------------------------
 repeatable read
(1 row)

A修改資料並且commit, epmdb=> start transaction ;
START TRANSACTION
epmdb=> update t1.dbversion  set  value =66  where dbversionid=1;
UPDATE 1
epmdb=> commit;
COMMIT
epmdb=> start TRANSACTION ;
START TRANSACTION
epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    99 |                100 |                 1
(1 row)

B在A修改後,提交後查詢,資料未修改:

epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    99 |                100 |                 1
(1 row)


epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    99 |                100 |                 1
(1 row)


epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    99 |                100 |                 1
(1 row)
B 提交事務,再次查詢: epmdb=> commit;
COMMIT
epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    66 |                100 |                 1
(1 row)

在事務進行中,其他事務的提交不會影響當前事務

4. serialable


epmdb=> show default_transaction_isolation ;
 default_transaction_isolation 
-------------------------------
 serializable
(1 row)

修改隔離級別一定要開啟事務,然後修改,再提交,直接set  不會生效。

B開啟事務,查詢:

epmdb=> start transaction ;
START TRANSACTION
epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    66 |                100 |                 1
           2 |     3 |                  4 |                50
(2 rows)


epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    66 |                100 |                 1
           2 |     3 |                  4 |                50
(2 rows)

A開啟事務,試圖修改或者插入:

epmdb=> start  transaction ;
START TRANSACTION
epmdb=> select * from t1.dbversion ;
 dbversionid | value | currentdataversion | targetdataversion 
-------------+-------+--------------------+-------------------
           1 |    66 |                100 |                 1
           2 |     3 |                  4 |                50
(2 rows)

START TRANSACTION
epmdb=> update t1.dbversion  set  value =644446  where dbversionid=1;
UPDATE 1
epmdb=> insert into t1.dbversion (dbversionid,value,currentdataversion,targetdataversion) values(12444,3,4,50);
INSERT 0 1
epmdb=> commit;
COMMIT
  

都成功,查詢文件,得知,serial是把事務並行提交,轉換為序列執行

Suppose that serializable transaction A computes:

SELECT SUM(value) FROM mytab WHERE class = 1;

and then inserts the result (30) as the value in a new row with class = 2. Concurrently, serializable transaction B computes:

SELECT SUM(value) FROM mytab WHERE class = 2;

and obtains the result 300, which it inserts in a new row with class = 1. Then both transactions try to commit. If either transaction were running at the Repeatable Read isolation level, both would be allowed to commit; but since there is no serial order of execution consistent with the result, using Serializable transactions will allow one transaction to commit and will roll the other back with this message:

ERROR:  could not serialize access due to read/write dependencies among transactions
由於無法測試同時提交兩個查詢,無法測試