mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Bug#20837 Apparent change of isolation level during transaction
Bug#46527 COMMIT AND CHAIN RELEASE does not make sense Bug#53343 completion_type=1, COMMIT/ROLLBACK AND CHAIN don't preserve the isolation level Bug#53346 completion_type has strange effect in a stored procedure/prepared statement Added test cases to verify the expected behaviour of : SET SESSION TRANSACTION ISOLATION LEVEL, SET TRANSACTION ISOLATION LEVEL, @@completion_type, COMMIT AND CHAIN, ROLLBACK AND CHAIN ..and some combinations of the above
This commit is contained in:
commit
0cb90edfe5
19 changed files with 939 additions and 64 deletions
272
mysql-test/r/commit.result
Normal file
272
mysql-test/r/commit.result
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
#
|
||||||
|
# Bug#20837 Apparent change of isolation level
|
||||||
|
# during transaction
|
||||||
|
#
|
||||||
|
# Bug#53343 completion_type=1, COMMIT/ROLLBACK
|
||||||
|
# AND CHAIN don't preserve the isolation
|
||||||
|
# level
|
||||||
|
connection default;
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
CREATE TABLE t1 (s1 INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
COMMIT;
|
||||||
|
START TRANSACTION;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
ERROR 25001: Transaction isolation level can't be changed while a transaction is in progress
|
||||||
|
COMMIT;
|
||||||
|
SET @@autocommit=0;
|
||||||
|
COMMIT;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT @@tx_isolation;
|
||||||
|
@@tx_isolation
|
||||||
|
REPEATABLE-READ
|
||||||
|
Should be REPEATABLE READ
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
SELECT @@tx_isolation;
|
||||||
|
@@tx_isolation
|
||||||
|
REPEATABLE-READ
|
||||||
|
Should be REPEATABLE READ
|
||||||
|
INSERT INTO t1 VALUES (-1);
|
||||||
|
SELECT @@tx_isolation;
|
||||||
|
@@tx_isolation
|
||||||
|
REPEATABLE-READ
|
||||||
|
Should be REPEATABLE READ
|
||||||
|
COMMIT;
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
connection con1
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1000);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
We should not be able to read the '1000'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
COMMIT;
|
||||||
|
Now, the '1000' should appear.
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
1000
|
||||||
|
COMMIT;
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
connection default
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
connection con1
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1001;
|
||||||
|
COUNT(*)
|
||||||
|
1
|
||||||
|
Should be 1
|
||||||
|
COMMIT AND CHAIN;
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1002;
|
||||||
|
COUNT(*)
|
||||||
|
1
|
||||||
|
Should be 1
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
1000
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
connection con1
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1001;
|
||||||
|
COUNT(*)
|
||||||
|
1
|
||||||
|
Should be 1
|
||||||
|
ROLLBACK AND CHAIN;
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1002;
|
||||||
|
COUNT(*)
|
||||||
|
1
|
||||||
|
Should be 1
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT;
|
||||||
|
SET @@completion_type=1;
|
||||||
|
connection default
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
connection con1
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
s1
|
||||||
|
1001
|
||||||
|
Should see 1001
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
default transaction is now in REPEATABLE READ
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
s1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
Should see 1001 and 1002
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1003);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
s1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
Should see 1001 and 1002, but NOT 1003
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
1003
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET @@completion_type=0;
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SET @@completion_type=1;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
connection con1
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
s1
|
||||||
|
1001
|
||||||
|
Should see 1001
|
||||||
|
ROLLBACK AND NO CHAIN;
|
||||||
|
default transaction is now in REPEATABLE READ
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
s1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
Should see 1001 and 1002
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1003);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
s1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
Should see 1001 and 1002, but NOT 1003
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
1001
|
||||||
|
1002
|
||||||
|
1003
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET @@completion_type=0;
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1000);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-1
|
||||||
|
Should get same result as above (i.e should not read '1000')
|
||||||
|
COMMIT;
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT;
|
||||||
|
SET @@completion_type=1;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES (1000);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1000
|
||||||
|
Should read '1000'
|
||||||
|
connection con1
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
connection default
|
||||||
|
SELECT * FROM t1;
|
||||||
|
s1
|
||||||
|
1000
|
||||||
|
Should only read the '1000' as this transaction is now in REP READ
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET @@completion_type=0;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET @autocommit=1;
|
||||||
|
COMMIT;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End of test cases for Bug#20837
|
||||||
|
#
|
|
@ -618,3 +618,48 @@ DROP TABLE t1, t2, t3;
|
||||||
#
|
#
|
||||||
# End of 5.1 tests
|
# End of 5.1 tests
|
||||||
#
|
#
|
||||||
|
# Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense"
|
||||||
|
#
|
||||||
|
COMMIT AND CHAIN RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1
|
||||||
|
COMMIT AND NO CHAIN RELEASE;
|
||||||
|
COMMIT RELEASE;
|
||||||
|
COMMIT CHAIN RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1
|
||||||
|
COMMIT NO CHAIN RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1
|
||||||
|
COMMIT AND NO RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1
|
||||||
|
COMMIT AND RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1
|
||||||
|
COMMIT NO RELEASE;
|
||||||
|
COMMIT CHAIN NO RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1
|
||||||
|
COMMIT NO CHAIN NO RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1
|
||||||
|
COMMIT AND RELEASE CHAIN;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1
|
||||||
|
COMMIT AND NO CHAIN NO RELEASE;
|
||||||
|
ROLLBACK AND CHAIN RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1
|
||||||
|
ROLLBACK AND NO CHAIN RELEASE;
|
||||||
|
ROLLBACK RELEASE;
|
||||||
|
ROLLBACK CHAIN RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1
|
||||||
|
ROLLBACK NO CHAIN RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1
|
||||||
|
ROLLBACK AND NO RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1
|
||||||
|
ROLLBACK AND RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1
|
||||||
|
ROLLBACK NO RELEASE;
|
||||||
|
ROLLBACK CHAIN NO RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1
|
||||||
|
ROLLBACK NO CHAIN NO RELEASE;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1
|
||||||
|
ROLLBACK AND RELEASE CHAIN;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1
|
||||||
|
ROLLBACK AND NO CHAIN NO RELEASE;
|
||||||
|
#
|
||||||
|
# End of 5.5 tests
|
||||||
|
#
|
||||||
|
|
|
@ -18,6 +18,7 @@ set autocommit=0;
|
||||||
update t1 set a=10 where a=5;
|
update t1 set a=10 where a=5;
|
||||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
commit;
|
commit;
|
||||||
|
commit;
|
||||||
set session transaction isolation level read committed;
|
set session transaction isolation level read committed;
|
||||||
update t1 set a=10 where a=5;
|
update t1 set a=10 where a=5;
|
||||||
select * from t1 where a=2 for update;
|
select * from t1 where a=2 for update;
|
||||||
|
|
|
@ -695,11 +695,11 @@ REPEATABLE-READ
|
||||||
set transaction isolation level read committed;
|
set transaction isolation level read committed;
|
||||||
execute stmt;
|
execute stmt;
|
||||||
@@tx_isolation
|
@@tx_isolation
|
||||||
READ-COMMITTED
|
REPEATABLE-READ
|
||||||
set transaction isolation level serializable;
|
set transaction isolation level serializable;
|
||||||
execute stmt;
|
execute stmt;
|
||||||
@@tx_isolation
|
@@tx_isolation
|
||||||
SERIALIZABLE
|
REPEATABLE-READ
|
||||||
set @@tx_isolation=default;
|
set @@tx_isolation=default;
|
||||||
execute stmt;
|
execute stmt;
|
||||||
@@tx_isolation
|
@@tx_isolation
|
||||||
|
|
|
@ -2,65 +2,65 @@ SET BINLOG_FORMAT=MIXED;
|
||||||
RESET MASTER;
|
RESET MASTER;
|
||||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
|
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
|
||||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
|
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 1;
|
UPDATE t1 SET b = 2*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = a * a WHERE a > 3;
|
UPDATE t1 SET b = a * a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SET BINLOG_FORMAT=STATEMENT;
|
SET BINLOG_FORMAT=STATEMENT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||||
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
|
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||||
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
|
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 3*a WHERE a > 3;
|
UPDATE t1 SET b = 3*a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 4*a WHERE a > 4;
|
UPDATE t1 SET b = 4*a WHERE a > 4;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SET BINLOG_FORMAT=MIXED;
|
SET BINLOG_FORMAT=MIXED;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 3*a WHERE a > 3;
|
UPDATE t1 SET b = 3*a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 4*a WHERE a > 4;
|
UPDATE t1 SET b = 4*a WHERE a > 4;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SET BINLOG_FORMAT=ROW;
|
SET BINLOG_FORMAT=ROW;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 3*a WHERE a > 3;
|
UPDATE t1 SET b = 3*a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 4*a WHERE a > 4;
|
UPDATE t1 SET b = 4*a WHERE a > 4;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
show binlog events from <binlog_start>;
|
show binlog events from <binlog_start>;
|
||||||
|
|
|
@ -8,14 +8,14 @@ RESET MASTER;
|
||||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
|
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB;
|
||||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
|
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
# Should be logged as statement
|
# Should be logged as statement
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 1;
|
UPDATE t1 SET b = 2*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
# Should be logged as rows
|
# Should be logged as rows
|
||||||
UPDATE t1 SET b = a * a WHERE a > 3;
|
UPDATE t1 SET b = a * a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
@ -25,69 +25,69 @@ COMMIT;
|
||||||
|
|
||||||
SET BINLOG_FORMAT=STATEMENT;
|
SET BINLOG_FORMAT=STATEMENT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
BEGIN;
|
||||||
error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE;
|
error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE;
|
||||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE;
|
error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 3*a WHERE a > 3;
|
UPDATE t1 SET b = 3*a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 4*a WHERE a > 4;
|
UPDATE t1 SET b = 4*a WHERE a > 4;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
SET BINLOG_FORMAT=MIXED;
|
SET BINLOG_FORMAT=MIXED;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 3*a WHERE a > 3;
|
UPDATE t1 SET b = 3*a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 4*a WHERE a > 4;
|
UPDATE t1 SET b = 4*a WHERE a > 4;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
SET BINLOG_FORMAT=ROW;
|
SET BINLOG_FORMAT=ROW;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 1*a WHERE a > 1;
|
UPDATE t1 SET b = 1*a WHERE a > 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 2*a WHERE a > 2;
|
UPDATE t1 SET b = 2*a WHERE a > 2;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 3*a WHERE a > 3;
|
UPDATE t1 SET b = 3*a WHERE a > 3;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
BEGIN;
|
||||||
UPDATE t1 SET b = 4*a WHERE a > 4;
|
UPDATE t1 SET b = 4*a WHERE a > 4;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
|
350
mysql-test/t/commit.test
Normal file
350
mysql-test/t/commit.test
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
connect (con1,localhost,root,,);
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#20837 Apparent change of isolation level
|
||||||
|
--echo # during transaction
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#53343 completion_type=1, COMMIT/ROLLBACK
|
||||||
|
--echo # AND CHAIN don't preserve the isolation
|
||||||
|
--echo # level
|
||||||
|
#
|
||||||
|
# A set of test cases that verifies operation of
|
||||||
|
# transaction isolation level and chaining is
|
||||||
|
# provided
|
||||||
|
|
||||||
|
# init
|
||||||
|
--echo connection default;
|
||||||
|
connection default;
|
||||||
|
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
CREATE TABLE t1 (s1 INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify that SET TRANS ISO LEVEL is not allowed
|
||||||
|
# inside a transaction
|
||||||
|
#
|
||||||
|
START TRANSACTION;
|
||||||
|
--error ER_CANT_CHANGE_TX_ISOLATION
|
||||||
|
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify consistent output from
|
||||||
|
# SELECT @@tx_isolation (Bug#20837)
|
||||||
|
#
|
||||||
|
# The transaction will be in READ UNCOMMITTED mode,
|
||||||
|
# but SELECT @@tx_isolation should report the session
|
||||||
|
# value, which is REPEATABLE READ
|
||||||
|
#
|
||||||
|
SET @@autocommit=0;
|
||||||
|
COMMIT;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT @@tx_isolation;
|
||||||
|
--echo Should be REPEATABLE READ
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT @@tx_isolation;
|
||||||
|
--echo Should be REPEATABLE READ
|
||||||
|
INSERT INTO t1 VALUES (-1);
|
||||||
|
SELECT @@tx_isolation;
|
||||||
|
--echo Should be REPEATABLE READ
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify that a change in the session variable
|
||||||
|
# does not affect the currently started
|
||||||
|
# transaction
|
||||||
|
#
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1000);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
--echo We should not be able to read the '1000'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo Now, the '1000' should appear.
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
# restore the session value
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
|
||||||
|
#
|
||||||
|
# A set of test cases for verification that
|
||||||
|
# isolation level during chaining works. MySQL
|
||||||
|
# has three variants of chaining, i.e
|
||||||
|
# COMMIT AND CHAIN, ROLLBACK AND CHAIN, and
|
||||||
|
# the use of @completion_type
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify isolation level with COMMIT AND CHAIN
|
||||||
|
#
|
||||||
|
# COMMIT AND CHAIN causes a new transaction to
|
||||||
|
# begin as soon as the current ends, and the new
|
||||||
|
# transaction will have the same tran. iso. level
|
||||||
|
# as the first.
|
||||||
|
#
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1001;
|
||||||
|
--echo Should be 1
|
||||||
|
COMMIT AND CHAIN;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1002;
|
||||||
|
--echo Should be 1
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify isolation level with ROLLBACK AND CHAIN
|
||||||
|
#
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1001;
|
||||||
|
--echo Should be 1
|
||||||
|
ROLLBACK AND CHAIN;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT COUNT(*) FROM t1 WHERE s1 = 1002;
|
||||||
|
--echo Should be 1
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify isolation level with @completion_type=1.
|
||||||
|
# (A @@completion_type value of 1 is equivalentl to
|
||||||
|
# explicitly adding "AND CHAIN" to COMMIT or ROLLBACK)
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify that COMMIT AND NO CHAIN overrides the value
|
||||||
|
# of @@completion_type
|
||||||
|
#
|
||||||
|
SET @@completion_type=1;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
--echo Should see 1001
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
--echo default transaction is now in REPEATABLE READ
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
--echo Should see 1001 and 1002
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1003);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
--echo Should see 1001 and 1002, but NOT 1003
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET @@completion_type=0;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify that ROLLBACK AND NO CHAIN overrides the value
|
||||||
|
# of @@completion_type
|
||||||
|
#
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SET @@completion_type=1;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
--echo Should see 1001
|
||||||
|
ROLLBACK AND NO CHAIN;
|
||||||
|
--echo default transaction is now in REPEATABLE READ
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1002);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
--echo Should see 1001 and 1002
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1003);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1 WHERE s1 >= 1000;
|
||||||
|
--echo Should see 1001 and 1002, but NOT 1003
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET @@completion_type=0;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify that in the sequence:
|
||||||
|
# SET TRANSACTION ISOLATION LEVEL
|
||||||
|
# SET SESSION ISOLATION LEVEL
|
||||||
|
#
|
||||||
|
# SET SESSION ISOLATION LEVEL has precedence over
|
||||||
|
# SET TRANSACTION. (Note that this is _not_
|
||||||
|
# in accordance with ISO 9075.)
|
||||||
|
#
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||||
|
START TRANSACTION;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1000);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--echo Should get same result as above (i.e should not read '1000')
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
DELETE FROM t1 WHERE s1 >= 1000;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify that a transaction ended with an
|
||||||
|
# implicit commit (i.e a DDL statement), the
|
||||||
|
# @@completetion_type setting is ignored, and
|
||||||
|
# the next transaction's isolation level is
|
||||||
|
# the session level.
|
||||||
|
#
|
||||||
|
SET @@completion_type=1;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
START TRANSACTION;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES (1000);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--echo Should read '1000'
|
||||||
|
|
||||||
|
--echo connection con1
|
||||||
|
connection con1;
|
||||||
|
INSERT INTO t1 VALUES (1001);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
--echo connection default
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--echo Should only read the '1000' as this transaction is now in REP READ
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
|
||||||
|
SET @@completion_type=0;
|
||||||
|
COMMIT AND NO CHAIN;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cleanup
|
||||||
|
#
|
||||||
|
SET @autocommit=1;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
disconnect con1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of test cases for Bug#20837
|
||||||
|
--echo #
|
|
@ -732,3 +732,79 @@ DROP TABLE t1, t2, t3;
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 5.1 tests
|
--echo # End of 5.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo # Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense"
|
||||||
|
--echo #
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT AND CHAIN RELEASE;
|
||||||
|
|
||||||
|
COMMIT AND NO CHAIN RELEASE;
|
||||||
|
disconnect default;
|
||||||
|
connect(default, localhost, root,,);
|
||||||
|
|
||||||
|
COMMIT RELEASE;
|
||||||
|
disconnect default;
|
||||||
|
connect(default, localhost, root,,);
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT CHAIN RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT NO CHAIN RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT AND NO RELEASE;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT AND RELEASE;
|
||||||
|
|
||||||
|
COMMIT NO RELEASE;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT CHAIN NO RELEASE;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT NO CHAIN NO RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
COMMIT AND RELEASE CHAIN;
|
||||||
|
|
||||||
|
COMMIT AND NO CHAIN NO RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK AND CHAIN RELEASE;
|
||||||
|
|
||||||
|
ROLLBACK AND NO CHAIN RELEASE;
|
||||||
|
disconnect default;
|
||||||
|
connect(default, localhost, root,,);
|
||||||
|
|
||||||
|
ROLLBACK RELEASE;
|
||||||
|
disconnect default;
|
||||||
|
connect(default, localhost, root,,);
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK CHAIN RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK NO CHAIN RELEASE;
|
||||||
|
disconnect default;
|
||||||
|
connect(default, localhost, root,,);
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK AND NO RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK AND RELEASE;
|
||||||
|
|
||||||
|
ROLLBACK NO RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK CHAIN NO RELEASE;
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK NO CHAIN NO RELEASE;
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
ROLLBACK AND RELEASE CHAIN;
|
||||||
|
|
||||||
|
ROLLBACK AND NO CHAIN NO RELEASE;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 5.5 tests
|
||||||
|
--echo #
|
||||||
|
|
|
@ -31,6 +31,7 @@ set session transaction isolation level repeatable read;
|
||||||
set autocommit=0;
|
set autocommit=0;
|
||||||
-- error ER_LOCK_WAIT_TIMEOUT
|
-- error ER_LOCK_WAIT_TIMEOUT
|
||||||
update t1 set a=10 where a=5;
|
update t1 set a=10 where a=5;
|
||||||
|
commit;
|
||||||
connection a;
|
connection a;
|
||||||
#DELETE FROM t1 WHERE a=5;
|
#DELETE FROM t1 WHERE a=5;
|
||||||
commit;
|
commit;
|
||||||
|
|
|
@ -1302,7 +1302,6 @@ int ha_commit_one_phase(THD *thd, bool all)
|
||||||
if (thd->transaction.changed_tables)
|
if (thd->transaction.changed_tables)
|
||||||
query_cache.invalidate(thd->transaction.changed_tables);
|
query_cache.invalidate(thd->transaction.changed_tables);
|
||||||
#endif
|
#endif
|
||||||
thd->variables.tx_isolation=thd->session_tx_isolation;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Free resources and perform other cleanup even for 'empty' transactions. */
|
/* Free resources and perform other cleanup even for 'empty' transactions. */
|
||||||
|
@ -1379,8 +1378,6 @@ int ha_rollback_trans(THD *thd, bool all)
|
||||||
if (is_real_trans && thd->transaction_rollback_request &&
|
if (is_real_trans && thd->transaction_rollback_request &&
|
||||||
thd->transaction.xid_state.xa_state != XA_NOTR)
|
thd->transaction.xid_state.xa_state != XA_NOTR)
|
||||||
thd->transaction.xid_state.rm_error= thd->stmt_da->sql_errno();
|
thd->transaction.xid_state.rm_error= thd->stmt_da->sql_errno();
|
||||||
if (all)
|
|
||||||
thd->variables.tx_isolation=thd->session_tx_isolation;
|
|
||||||
}
|
}
|
||||||
/* Always cleanup. Even if nht==0. There may be savepoints. */
|
/* Always cleanup. Even if nht==0. There may be savepoints. */
|
||||||
if (is_real_trans)
|
if (is_real_trans)
|
||||||
|
|
|
@ -353,7 +353,7 @@ int thd_sql_command(const THD *thd)
|
||||||
extern "C"
|
extern "C"
|
||||||
int thd_tx_isolation(const THD *thd)
|
int thd_tx_isolation(const THD *thd)
|
||||||
{
|
{
|
||||||
return (int) thd->variables.tx_isolation;
|
return (int) thd->tx_isolation;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -957,7 +957,7 @@ void THD::init(void)
|
||||||
update_lock_default= (variables.low_priority_updates ?
|
update_lock_default= (variables.low_priority_updates ?
|
||||||
TL_WRITE_LOW_PRIORITY :
|
TL_WRITE_LOW_PRIORITY :
|
||||||
TL_WRITE);
|
TL_WRITE);
|
||||||
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
|
tx_isolation= (enum_tx_isolation) variables.tx_isolation;
|
||||||
update_charset();
|
update_charset();
|
||||||
reset_current_stmt_binlog_format_row();
|
reset_current_stmt_binlog_format_row();
|
||||||
bzero((char *) &status_var, sizeof(status_var));
|
bzero((char *) &status_var, sizeof(status_var));
|
||||||
|
|
|
@ -1941,8 +1941,31 @@ public:
|
||||||
uint server_status,open_options;
|
uint server_status,open_options;
|
||||||
enum enum_thread_type system_thread;
|
enum enum_thread_type system_thread;
|
||||||
uint select_number; //number of select (used for EXPLAIN)
|
uint select_number; //number of select (used for EXPLAIN)
|
||||||
/* variables.transaction_isolation is reset to this after each commit */
|
/*
|
||||||
enum_tx_isolation session_tx_isolation;
|
Current or next transaction isolation level.
|
||||||
|
When a connection is established, the value is taken from
|
||||||
|
@@session.tx_isolation (default transaction isolation for
|
||||||
|
the session), which is in turn taken from @@global.tx_isolation
|
||||||
|
(the global value).
|
||||||
|
If there is no transaction started, this variable
|
||||||
|
holds the value of the next transaction's isolation level.
|
||||||
|
When a transaction starts, the value stored in this variable
|
||||||
|
becomes "actual".
|
||||||
|
At transaction commit or rollback, we assign this variable
|
||||||
|
again from @@session.tx_isolation.
|
||||||
|
The only statement that can otherwise change the value
|
||||||
|
of this variable is SET TRANSACTION ISOLATION LEVEL.
|
||||||
|
Its purpose is to effect the isolation level of the next
|
||||||
|
transaction in this session. When this statement is executed,
|
||||||
|
the value in this variable is changed. However, since
|
||||||
|
this statement is only allowed when there is no active
|
||||||
|
transaction, this assignment (naturally) only affects the
|
||||||
|
upcoming transaction.
|
||||||
|
At the end of the current active transaction the value is
|
||||||
|
be reset again from @@session.tx_isolation, as described
|
||||||
|
above.
|
||||||
|
*/
|
||||||
|
enum_tx_isolation tx_isolation;
|
||||||
enum_check_fields count_cuted_fields;
|
enum_check_fields count_cuted_fields;
|
||||||
|
|
||||||
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
|
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
|
||||||
|
|
|
@ -1975,7 +1975,7 @@ struct LEX: public Query_tables_list
|
||||||
bool autocommit;
|
bool autocommit;
|
||||||
bool verbose, no_write_to_binlog;
|
bool verbose, no_write_to_binlog;
|
||||||
|
|
||||||
bool tx_chain, tx_release;
|
enum enum_yes_no_unknown tx_chain, tx_release;
|
||||||
/*
|
/*
|
||||||
Special JOIN::prepare mode: changing of query is prohibited.
|
Special JOIN::prepare mode: changing of query is prohibited.
|
||||||
When creating a view, we need to just check its syntax omitting
|
When creating a view, we need to just check its syntax omitting
|
||||||
|
|
|
@ -4078,33 +4078,65 @@ end_with_restore_list:
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_COMMIT:
|
case SQLCOM_COMMIT:
|
||||||
|
{
|
||||||
DBUG_ASSERT(thd->lock == NULL ||
|
DBUG_ASSERT(thd->lock == NULL ||
|
||||||
thd->locked_tables_mode == LTM_LOCK_TABLES);
|
thd->locked_tables_mode == LTM_LOCK_TABLES);
|
||||||
|
bool tx_chain= (lex->tx_chain == TVL_YES ||
|
||||||
|
(thd->variables.completion_type == 1 &&
|
||||||
|
lex->tx_chain != TVL_NO));
|
||||||
|
bool tx_release= (lex->tx_release == TVL_YES ||
|
||||||
|
(thd->variables.completion_type == 2 &&
|
||||||
|
lex->tx_release != TVL_NO));
|
||||||
if (trans_commit(thd))
|
if (trans_commit(thd))
|
||||||
goto error;
|
goto error;
|
||||||
thd->mdl_context.release_transactional_locks();
|
thd->mdl_context.release_transactional_locks();
|
||||||
/* Begin transaction with the same isolation level. */
|
/* Begin transaction with the same isolation level. */
|
||||||
if (lex->tx_chain && trans_begin(thd))
|
if (tx_chain)
|
||||||
|
{
|
||||||
|
if (trans_begin(thd))
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reset the isolation level if no chaining transaction. */
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
|
}
|
||||||
/* Disconnect the current client connection. */
|
/* Disconnect the current client connection. */
|
||||||
if (lex->tx_release)
|
if (tx_release)
|
||||||
thd->killed= THD::KILL_CONNECTION;
|
thd->killed= THD::KILL_CONNECTION;
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_ROLLBACK:
|
case SQLCOM_ROLLBACK:
|
||||||
|
{
|
||||||
DBUG_ASSERT(thd->lock == NULL ||
|
DBUG_ASSERT(thd->lock == NULL ||
|
||||||
thd->locked_tables_mode == LTM_LOCK_TABLES);
|
thd->locked_tables_mode == LTM_LOCK_TABLES);
|
||||||
|
bool tx_chain= (lex->tx_chain == TVL_YES ||
|
||||||
|
(thd->variables.completion_type == 1 &&
|
||||||
|
lex->tx_chain != TVL_NO));
|
||||||
|
bool tx_release= (lex->tx_release == TVL_YES ||
|
||||||
|
(thd->variables.completion_type == 2 &&
|
||||||
|
lex->tx_release != TVL_NO));
|
||||||
if (trans_rollback(thd))
|
if (trans_rollback(thd))
|
||||||
goto error;
|
goto error;
|
||||||
thd->mdl_context.release_transactional_locks();
|
thd->mdl_context.release_transactional_locks();
|
||||||
/* Begin transaction with the same isolation level. */
|
/* Begin transaction with the same isolation level. */
|
||||||
if (lex->tx_chain && trans_begin(thd))
|
if (tx_chain)
|
||||||
goto error;
|
{
|
||||||
|
if (trans_begin(thd))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reset the isolation level if no chaining transaction. */
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
|
}
|
||||||
/* Disconnect the current client connection. */
|
/* Disconnect the current client connection. */
|
||||||
if (lex->tx_release)
|
if (tx_release)
|
||||||
thd->killed= THD::KILL_CONNECTION;
|
thd->killed= THD::KILL_CONNECTION;
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_RELEASE_SAVEPOINT:
|
case SQLCOM_RELEASE_SAVEPOINT:
|
||||||
if (trans_release_savepoint(thd, lex->ident))
|
if (trans_release_savepoint(thd, lex->ident))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -4607,12 +4639,22 @@ create_sp_error:
|
||||||
if (trans_xa_commit(thd))
|
if (trans_xa_commit(thd))
|
||||||
goto error;
|
goto error;
|
||||||
thd->mdl_context.release_transactional_locks();
|
thd->mdl_context.release_transactional_locks();
|
||||||
|
/*
|
||||||
|
We've just done a commit, reset transaction
|
||||||
|
isolation level to the session default.
|
||||||
|
*/
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_XA_ROLLBACK:
|
case SQLCOM_XA_ROLLBACK:
|
||||||
if (trans_xa_rollback(thd))
|
if (trans_xa_rollback(thd))
|
||||||
goto error;
|
goto error;
|
||||||
thd->mdl_context.release_transactional_locks();
|
thd->mdl_context.release_transactional_locks();
|
||||||
|
/*
|
||||||
|
We've just done a rollback, reset transaction
|
||||||
|
isolation level to the session default.
|
||||||
|
*/
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_XA_RECOVER:
|
case SQLCOM_XA_RECOVER:
|
||||||
|
|
|
@ -211,6 +211,11 @@ enum enum_var_type
|
||||||
|
|
||||||
class sys_var;
|
class sys_var;
|
||||||
|
|
||||||
|
enum enum_yes_no_unknown
|
||||||
|
{
|
||||||
|
TVL_YES, TVL_NO, TVL_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef MYSQL_SERVER
|
#ifdef MYSQL_SERVER
|
||||||
|
|
||||||
#endif /* MYSQL_SERVER */
|
#endif /* MYSQL_SERVER */
|
||||||
|
|
|
@ -767,6 +767,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
|
||||||
enum index_hint_type index_hint;
|
enum index_hint_type index_hint;
|
||||||
enum enum_filetype filetype;
|
enum enum_filetype filetype;
|
||||||
enum Foreign_key::fk_option m_fk_option;
|
enum Foreign_key::fk_option m_fk_option;
|
||||||
|
enum enum_yes_no_unknown m_yes_no_unk;
|
||||||
Diag_condition_item_name diag_condition_item_name;
|
Diag_condition_item_name diag_condition_item_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,12 +1435,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
table_option opt_if_not_exists opt_no_write_to_binlog
|
table_option opt_if_not_exists opt_no_write_to_binlog
|
||||||
opt_temporary all_or_any opt_distinct
|
opt_temporary all_or_any opt_distinct
|
||||||
opt_ignore_leaves fulltext_options spatial_type union_option
|
opt_ignore_leaves fulltext_options spatial_type union_option
|
||||||
start_transaction_opts opt_chain opt_release
|
start_transaction_opts
|
||||||
union_opt select_derived_init option_type2
|
union_opt select_derived_init option_type2
|
||||||
opt_natural_language_mode opt_query_expansion
|
opt_natural_language_mode opt_query_expansion
|
||||||
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
|
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
|
||||||
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
|
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
|
||||||
|
|
||||||
|
%type <m_yes_no_unk>
|
||||||
|
opt_chain opt_release
|
||||||
|
|
||||||
%type <m_fk_option>
|
%type <m_fk_option>
|
||||||
delete_option
|
delete_option
|
||||||
|
|
||||||
|
@ -13602,16 +13606,16 @@ opt_work:
|
||||||
|
|
||||||
opt_chain:
|
opt_chain:
|
||||||
/* empty */
|
/* empty */
|
||||||
{ $$= (YYTHD->variables.completion_type == 1); }
|
{ $$= TVL_UNKNOWN; }
|
||||||
| AND_SYM NO_SYM CHAIN_SYM { $$=0; }
|
| AND_SYM NO_SYM CHAIN_SYM { $$= TVL_NO; }
|
||||||
| AND_SYM CHAIN_SYM { $$=1; }
|
| AND_SYM CHAIN_SYM { $$= TVL_YES; }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_release:
|
opt_release:
|
||||||
/* empty */
|
/* empty */
|
||||||
{ $$= (YYTHD->variables.completion_type == 2); }
|
{ $$= TVL_UNKNOWN; }
|
||||||
| RELEASE_SYM { $$=1; }
|
| RELEASE_SYM { $$= TVL_YES; }
|
||||||
| NO_SYM RELEASE_SYM { $$=0; }
|
| NO_SYM RELEASE_SYM { $$= TVL_NO; }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_savepoint:
|
opt_savepoint:
|
||||||
|
@ -13624,7 +13628,9 @@ commit:
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command= SQLCOM_COMMIT;
|
lex->sql_command= SQLCOM_COMMIT;
|
||||||
lex->tx_chain= $3;
|
/* Don't allow AND CHAIN RELEASE. */
|
||||||
|
MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
|
||||||
|
lex->tx_chain= $3;
|
||||||
lex->tx_release= $4;
|
lex->tx_release= $4;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -13634,7 +13640,9 @@ rollback:
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command= SQLCOM_ROLLBACK;
|
lex->sql_command= SQLCOM_ROLLBACK;
|
||||||
lex->tx_chain= $3;
|
/* Don't allow AND CHAIN RELEASE. */
|
||||||
|
MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
|
||||||
|
lex->tx_chain= $3;
|
||||||
lex->tx_release= $4;
|
lex->tx_release= $4;
|
||||||
}
|
}
|
||||||
| ROLLBACK_SYM opt_work
|
| ROLLBACK_SYM opt_work
|
||||||
|
|
|
@ -2029,24 +2029,38 @@ static bool check_tx_isolation(sys_var *self, THD *thd, set_var *var)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
If one doesn't use the SESSION modifier, the isolation level
|
bool Sys_var_tx_isolation::session_update(THD *thd, set_var *var)
|
||||||
is only active for the next command.
|
|
||||||
*/
|
|
||||||
static bool fix_tx_isolation(sys_var *self, THD *thd, enum_var_type type)
|
|
||||||
{
|
{
|
||||||
if (type == OPT_SESSION)
|
if (var->type == OPT_SESSION && Sys_var_enum::session_update(thd, var))
|
||||||
thd->session_tx_isolation= (enum_tx_isolation)thd->variables.tx_isolation;
|
return TRUE;
|
||||||
return false;
|
if (var->type == OPT_DEFAULT || !thd->in_active_multi_stmt_transaction())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Update the isolation level of the next transaction.
|
||||||
|
I.e. if one did:
|
||||||
|
COMMIT;
|
||||||
|
SET SESSION ISOLATION LEVEL ...
|
||||||
|
BEGIN; <-- this transaction has the new isolation
|
||||||
|
Note, that in case of:
|
||||||
|
COMMIT;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL ...
|
||||||
|
SET SESSION ISOLATION LEVEL ...
|
||||||
|
BEGIN; <-- the session isolation level is used, not the
|
||||||
|
result of SET TRANSACTION statement.
|
||||||
|
*/
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) var->save_result.ulonglong_value;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// NO_CMD_LINE - different name of the option
|
// NO_CMD_LINE - different name of the option
|
||||||
static Sys_var_enum Sys_tx_isolation(
|
static Sys_var_tx_isolation Sys_tx_isolation(
|
||||||
"tx_isolation", "Default transaction isolation level",
|
"tx_isolation", "Default transaction isolation level",
|
||||||
SESSION_VAR(tx_isolation), NO_CMD_LINE,
|
SESSION_VAR(tx_isolation), NO_CMD_LINE,
|
||||||
tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ),
|
tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ),
|
||||||
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_isolation),
|
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_isolation));
|
||||||
ON_UPDATE(fix_tx_isolation));
|
|
||||||
|
|
||||||
static Sys_var_ulonglong Sys_tmp_table_size(
|
static Sys_var_ulonglong Sys_tmp_table_size(
|
||||||
"tmp_table_size",
|
"tmp_table_size",
|
||||||
|
|
|
@ -1599,6 +1599,22 @@ public:
|
||||||
{ return type != STRING_RESULT; }
|
{ return type != STRING_RESULT; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Sys_var_tx_isolation: public Sys_var_enum
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sys_var_tx_isolation(const char *name_arg,
|
||||||
|
const char *comment, int flag_args, ptrdiff_t off, size_t size,
|
||||||
|
CMD_LINE getopt,
|
||||||
|
const char *values[], uint def_val, PolyLock *lock,
|
||||||
|
enum binlog_status_enum binlog_status_arg,
|
||||||
|
on_check_function on_check_func)
|
||||||
|
:Sys_var_enum(name_arg, comment, flag_args, off, size, getopt,
|
||||||
|
values, def_val, lock, binlog_status_arg, on_check_func)
|
||||||
|
{}
|
||||||
|
virtual bool session_update(THD *thd, set_var *var);
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Used templates
|
Used templates
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
|
@ -96,7 +96,18 @@ bool trans_begin(THD *thd, uint flags)
|
||||||
|
|
||||||
DBUG_ASSERT(!thd->locked_tables_mode);
|
DBUG_ASSERT(!thd->locked_tables_mode);
|
||||||
|
|
||||||
if (trans_commit_implicit(thd))
|
if (thd->in_multi_stmt_transaction_mode() ||
|
||||||
|
(thd->variables.option_bits & OPTION_TABLE_LOCK))
|
||||||
|
{
|
||||||
|
thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
|
||||||
|
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||||
|
res= test(ha_commit_trans(thd, TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||||
|
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||||
|
|
||||||
|
if (res)
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -182,6 +193,14 @@ bool trans_commit_implicit(THD *thd)
|
||||||
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Upon implicit commit, reset the current transaction
|
||||||
|
isolation level. We do not care about
|
||||||
|
@@session.completion_type since it's documented
|
||||||
|
to not have any effect on implicit commit.
|
||||||
|
*/
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
|
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +253,11 @@ bool trans_commit_stmt(THD *thd)
|
||||||
DBUG_ENTER("trans_commit_stmt");
|
DBUG_ENTER("trans_commit_stmt");
|
||||||
int res= FALSE;
|
int res= FALSE;
|
||||||
if (thd->transaction.stmt.ha_list)
|
if (thd->transaction.stmt.ha_list)
|
||||||
|
{
|
||||||
res= ha_commit_trans(thd, FALSE);
|
res= ha_commit_trans(thd, FALSE);
|
||||||
|
if (! thd->in_active_multi_stmt_transaction())
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
|
}
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
/*
|
/*
|
||||||
|
@ -265,6 +288,8 @@ bool trans_rollback_stmt(THD *thd)
|
||||||
ha_rollback_trans(thd, FALSE);
|
ha_rollback_trans(thd, FALSE);
|
||||||
if (thd->transaction_rollback_request && !thd->in_sub_stmt)
|
if (thd->transaction_rollback_request && !thd->in_sub_stmt)
|
||||||
ha_rollback_trans(thd, TRUE);
|
ha_rollback_trans(thd, TRUE);
|
||||||
|
if (! thd->in_active_multi_stmt_transaction())
|
||||||
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_HOOK(transaction, after_rollback, (thd, FALSE));
|
RUN_HOOK(transaction, after_rollback, (thd, FALSE));
|
||||||
|
|
Loading…
Add table
Reference in a new issue