資料庫事務隔離級別測試-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的事務隔離級別,或者修改預設的事務隔離級別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)
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由於無法測試同時提交兩個查詢,無法測試