`
yuzhi2217
  • 浏览: 35039 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MySQL中的隔离级别和悲观锁及乐观锁示例

 
阅读更多

MySQL中的隔离级别和悲观锁及乐观锁示例

 

1MySQL的事支持 
MySQL
的事支持不是定在MySQL器本身,而是与存引擎相关:

 

  1. MyISAM:不支持事,用于只程序提高性能   
  2. InnoDB:支持ACID、行级锁、并   
  3. Berkeley DB:支持事  


2
隔离级别
隔离级别决定了一个session中的事可能另一个session的影响、并session数据的操作、一个session中所数据的一致性 
ANSI
准定4个隔离级别MySQLInnoDB都支持:

Java

  1. READ UNCOMMITTED:最低级别的隔离,通常又称dirty read,它允一个事务读commit的数据,这样可能会提高性能,但是dirty read可能不是我想要的   
  2. READ COMMITTED:在一个事中只允commit记录,如果sessionselect查询中,另一sessioninsert一条记录新添加的数据不可   
  3. REPEATABLE READ:在一个事开始后,其他session数据的修改在本事中不可,直到本事commitrollback。在一个事中重复select果一,除非本事update数据   
  4. SERIALIZABLE:最高级别的隔离,只允串行行。了达到此目的,数据住每行已经读取的记录,其他session不能修改数据直到前一事务结束,事commit或取消  

可以使用如下MySQLsession隔离级别

 

[c-sharp] view plaincopy
 
  1. 1.  SET TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}   

 

 

 

MySQL的隔离级别REPEATABLE READ,在置隔离级别为READ UNCOMMITTEDSERIALIZABLE要小心,READ UNCOMMITTED致数据完整性的问题,而SERIALIZABLE致性能问题并增加死的机率

 

 

3,隔离级别
乐观所和悲观锁策略: 
观锁:在取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结才能继续 
乐观所:取数据,更新时检查是否数据已被更新,如果是取消当前更新 
一般在悲
观锁的等待时间过长而不能接受才会选择乐观锁 
观锁的例子:

 

[c-sharp] view plaincopy
 
  1. CREATE PROCEDURE tfer_funds     
  2.        (from_account INT, to_account INT,tfer_amount NUMERIC(10,2),     
  3.         OUT status INT, OUT message VARCHAR(30))     
  4. BEGIN     
  5.     DECLARE from_account_balance NUMERIC(10,2);     
  6.     
  7.     START TRANSACTION;     
  8.     
  9.     
  10.     SELECT balance     
  11.       INTO from_account_balance     
  12.       FROM account_balance     
  13.      WHERE account_id=from_account     
  14.        FOR UPDATE;     
  15.     
  16.     IF from_account_balance>=tfer_amount THEN     
  17.     
  18.          UPDATE account_balance     
  19.             SET balance=balance-tfer_amount     
  20.           WHERE account_id=from_account;     
  21.     
  22.          UPDATE account_balance     
  23.             SET balance=balance+tfer_amount     
  24.           WHERE account_id=to_account;     
  25.          COMMIT;     
  26.     
  27.          SET status=0;     
  28.          SET message='OK';     
  29.     ELSE     
  30.          ROLLBACK;     
  31.          SET status=-1;     
  32.          SET message='Insufficient funds';     
  33.     END IF;     
  34. END;    

 

 

乐观锁的例子:

 

 

[c-sharp] view plaincopy
 
  1. CREATE PROCEDURE tfer_funds     
  2.     (from_account INT, to_account INT, tfer_amount NUMERIC(10,2),     
  3.         OUT status INT, OUT message VARCHAR(30) )     
  4.     
  5. BEGIN     
  6.     
  7.     DECLARE from_account_balance    NUMERIC(8,2);     
  8.     DECLARE from_account_balance2   NUMERIC(8,2);     
  9.     DECLARE from_account_timestamp1 TIMESTAMP;     
  10.     DECLARE from_account_timestamp2 TIMESTAMP;     
  11.     
  12.     SELECT account_timestamp,balance     
  13.         INTO from_account_timestamp1,from_account_balance     
  14.             FROM account_balance     
  15.             WHERE account_id=from_account;     
  16.     
  17.     IF (from_account_balance>=tfer_amount) THEN     
  18.     
  19.         -- Here we perform some long running validation that     
  20.         -- might take a few minutes */     
  21.         CALL long_running_validation(from_account);     
  22.     
  23.         START TRANSACTION;     
  24.     
  25.         -- Make sure the account row has not been updated since     
  26.         -- our initial check     
  27.         SELECT account_timestamp, balance     
  28.             INTO from_account_timestamp2,from_account_balance2     
  29.             FROM account_balance     
  30.             WHERE account_id=from_account     
  31.             FOR UPDATE;     
  32.     
  33.         IF (from_account_timestamp1 <> from_account_timestamp2 OR     
  34.             from_account_balance    <> from_account_balance2)  THEN     
  35.             ROLLBACK;     
  36.             SET status=-1;     
  37.             SET message=CONCAT("Transaction cancelled due to concurrent update",     
  38.                 " of account"  ,from_account);     
  39.         ELSE     
  40.             UPDATE account_balance     
  41.                 SET balance=balance-tfer_amount     
  42.                 WHERE account_id=from_account;     
  43.     
  44.             UPDATE account_balance     
  45.                 SET balance=balance+tfer_amount     
  46.                 WHERE account_id=to_account;     
  47.     
  48.             COMMIT;     
  49.     
  50.             SET status=0;     
  51.             SET message="OK";     
  52.         END IF;     
  53.     
  54.     ELSE     
  55.         ROLLBACK;     
  56.         SET status=-1;     
  57.         SET message="Insufficient funds";     
  58.     END IF;     
  59. END$$    
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics