感谢:MySQL数据库事务略知一二 和mysql共享锁与排他锁。通过他们两个人的博客,我学到了,不仅仅acid简单的概念和作用,还包括应用。其中,隔离性在并发事务处理中尤为重要,保证数据的一致性。

    下面的内容是自己总结包括摘抄他们的;

  ACID:事务的四大特性,即,原子性(automicity)、一致性(insistency)、隔离性(isolation)、持久性(durability).

    其中隔离性尤为重要,如果没有设置隔离级别,就会出现脏读、不可重复读、幻读。当然MySQL默认是innodb引擎,默认的隔离级别是repeatable read;有四种隔离级别:read uncommitted (读未提交) 是隔离级别最低。read committed (读已提交)能避免脏读,但会出现不可重复读和幻读。repeatable read(可重复读) 能避免脏读和不可重复读,会出现幻读。最后是 serializable (可串行化) 能避免所有问题。修改隔离级别,在mysql 文件下my.ini下。

        具体实现证明流程:请移步MySQL数据库事务略知一二里面有详细的讲解。

        部分内容摘抄如下;

  • 脏读 
    指一个事务读取了另外一个事务未提交的数据。 
    这是非常危险的,假设a向b转帐100元,对应sql语句如下所示:
1.update account set money=money+100 while name=‘b’;    
2.update account set money=money-100 while name=‘a’;

当第1条sql执行完,第2条还没执行(a未提交时),如果此时b查询自己的帐户,就会发现自己多了100元钱。如果a等b走后再回滚,b就会损失100元。

  • 不可重复读 
    在一个事务内读取表中的某一行数据,多次读取结果不同。(一个事务读取到了另外一个事务提交的数据) 
    例如银行想查询a帐户余额,第一次查询a帐户为200元,此时a向帐户内存了100元并提交了,银行接着又进行了一次查询,此时a帐户为300元了。银行两次查询不一致,可能就会很困惑,不知道哪次查询是准的。可将例子简化为:读表中某一行数据,例如a账户第一次读为1000,第二次读为1100。 
    不可重复读和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。 
    很多人认为这种情况就对了,无须困惑,当然是以后面的结果为准了。我们可以考虑这样一种情况,比如银行程序需要将查询结果分别输出到电脑屏幕和写到文件中,结果在一个事务中针对输出的目的地,进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作人员就不知道以哪个为准了。
  • 虚读(幻读) 
    虚读(幻读)是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。 
    如丙存款100元未提交,这时银行做报表统计account表中所有用户的总额为500元,然后丙提交了,这时银行再统计发现帐户为600元了,造成虚读同样会使银行不知所措,到底以哪个为准。可将例子简化为:读整个表,即表的行数,例如第一次读某个表有3条记录,第二次读该表又有4条记录。

下面讲讲排他锁和共享锁:

排它锁:其他事务对加了排他锁的数据行,不能读也不能写。设置排它锁本身的事务可以实现读写。可以使用select语句进行简单查询(不加锁)操作。

共享锁:其他事务能共享这个锁,能读不能写,能再加了共享锁的数据行,其他事务继续加共享锁(或不加锁)操作,但不能加排它锁。

mysql 对update insert delete会自动加上排它锁,基于innodb引擎。手动加 如select * from  test  for update;排它锁 lock in share mode;共享锁


具体实现证明例子:请移步:mysql共享锁与排他锁 。 我自己本地测试了下;一开始,忘记开启事务,后来开启事务后使用排它锁时,在执行加锁操作时,仍然能行。后来试了好久,都没有实现。就放弃了,等过了找工作阶段。再测试。