Commit 20e54ae6 authored by unknown's avatar unknown
Browse files

Fix for Bug #18184 SELECT ... FOR UPDATE does not work..: implemented...

Fix for Bug #18184  SELECT ... FOR UPDATE does not work..: implemented ha_ndblcuster::unlock_row() and explicitly lock all rows that are not being unlocked


parent 22e3b0c6
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -63,3 +63,62 @@ pk u o
5	5	5
insert into t1 values (1,1,1);
drop table t1;
create table t1 (x integer not null primary key, y varchar(32)) engine = ndb;
insert into t1 values (1,'one'), (2,'two'),(3,"three");
begin;
select * from t1 where x = 1 for update;
x	y
1	one
begin;
select * from t1 where x = 2 for update;
x	y
2	two
select * from t1 where x = 1 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
commit;
begin;
select * from t1 where y = 'one' or y = 'three' for update;
x	y
3	three
1	one
begin;
select * from t1 where x = 2 for update;
x	y
2	two
select * from t1 where x = 1 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
commit;
begin;
select * from t1 where x = 1 lock in share mode;
x	y
1	one
begin;
select * from t1 where x = 1 lock in share mode;
x	y
1	one
select * from t1 where x = 2 for update;
x	y
2	two
select * from t1 where x = 1 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
commit;
begin;
select * from t1 where y = 'one' or y = 'three' lock in share mode;
x	y
3	three
1	one
begin;
select * from t1 where y = 'one' lock in share mode;
x	y
1	one
select * from t1 where x = 2 for update;
x	y
2	two
select * from t1 where x = 1 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
commit;
drop table t1;
+76 −0
Original line number Diff line number Diff line
@@ -69,4 +69,80 @@ insert into t1 values (1,1,1);

drop table t1;

# Lock for update

create table t1 (x integer not null primary key, y varchar(32)) engine = ndb;

insert into t1 values (1,'one'), (2,'two'),(3,"three"); 

# PK access
connection con1;
begin;
select * from t1 where x = 1 for update;

connection con2;
begin;
select * from t1 where x = 2 for update;
--error 1205
select * from t1 where x = 1 for update;
rollback;

connection con1;
commit;

# scan
connection con1;
begin;
select * from t1 where y = 'one' or y = 'three' for update;

connection con2;
begin;
# Have to check with pk access here since scans take locks on
# all rows and then release them in chunks
select * from t1 where x = 2 for update;
--error 1205
select * from t1 where x = 1 for update;
rollback;

connection con1;
commit;

# share locking

# PK access
connection con1;
begin;
select * from t1 where x = 1 lock in share mode;

connection con2;
begin;
select * from t1 where x = 1 lock in share mode;
select * from t1 where x = 2 for update;
--error 1205
select * from t1 where x = 1 for update;
rollback;

connection con1;
commit;

# scan
connection con1;
begin;
select * from t1 where y = 'one' or y = 'three' lock in share mode;

connection con2;
begin;
select * from t1 where y = 'one' lock in share mode;
# Have to check with pk access here since scans take locks on
# all rows and then release them in chunks
select * from t1 where x = 2 for update;
--error 1205
select * from t1 where x = 1 for update;
rollback;

connection con1;
commit;

drop table t1;

# End of 4.1 tests
+4 −3
Original line number Diff line number Diff line
@@ -45,14 +45,15 @@ public:
  NdbResultSet* readTuples(LockMode = LM_Read,
			   Uint32 batch = 0, 
			   Uint32 parallel = 0,
			   bool order_by = false);
			   bool order_by = false,
			   bool keyinfo = false);
  
  inline NdbResultSet* readTuples(int parallell){
    return readTuples(LM_Read, 0, parallell, false);
    return readTuples(LM_Read, 0, parallell);
  }
  
  inline NdbResultSet* readTuplesExclusive(int parallell = 0){
    return readTuples(LM_Exclusive, 0, parallell, false);
    return readTuples(LM_Exclusive, 0, parallell);
  }

  /**
+21 −0
Original line number Diff line number Diff line
@@ -101,6 +101,27 @@ public:
   */
  int restart(bool forceSend = false);
  
  /**
   * Lock current row by transfering scan operation to a locking transaction. 
   * Use this function 
   * when a scan has found a record that you want to lock. 
   * 1. Start a new transaction.
   * 2. Call the function takeOverForUpdate using your new transaction 
   *    as parameter, all the properties of the found record will be copied 
   *    to the new transaction.
   * 3. When you execute the new transaction, the lock held by the scan will 
   *    be transferred to the new transaction(it's taken over).
   *
   * @note You must have started the scan with openScanExclusive
   *       or explictly have requested keyinfo to be able to lock 
   *       the found tuple.
   *
   * @param lockingTrans the locking transaction connection.
   * @return an NdbOperation or NULL.
   */
  NdbOperation* lockTuple();
  NdbOperation*	lockTuple(NdbConnection* lockingTrans);

  /**
   * Transfer scan operation to an updating transaction. Use this function 
   * when a scan has found a record that you want to update. 
+4 −2
Original line number Diff line number Diff line
@@ -64,14 +64,16 @@ public:
   * Tuples are not stored in NdbResultSet until execute(NoCommit) 
   * has been executed and nextResult has been called.
   * 
   * @param keyinfo   Return primary key, needed to be able to call lockTuple
   * @param parallel  Scan parallelism
   * @param batch No of rows to fetch from each fragment at a time
   * @param LockMode  Scan lock handling   
   * @returns NdbResultSet.
   * @note specifying 0 for batch and parallall means max performance
   * @note specifying 0 for batch and parallell means max performance
   */ 
  NdbResultSet* readTuples(LockMode = LM_Read, 
			   Uint32 batch = 0, Uint32 parallel = 0);
			   Uint32 batch = 0, Uint32 parallel = 0, 
			   bool keyinfo = false);
  
  inline NdbResultSet* readTuples(int parallell){
    return readTuples(LM_Read, 0, parallell);
Loading