事务    (原子性、一致性、隔离性、持久性)
     一、定义:
     事务是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。
     MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。 
     二、基本操作
          开始一个事务:
          start transaction; 
        创建一个保存点:
          savepoint 保存点名;
        回到保存点:
          roiiback;(若没有保存点,直接回滚到事务的开始)
          rollback to 保存点名;(不会结束事务)
        提交 :
         commit ;(一旦提交,无法回退(rollback));
        实例:
           create table account(  
           id int primary key,  
           name varchar(50) not null default '',   
           balance decimal(10, 2) not null default 0.0
           );
           start transaction; --开启事务 
           Query OK, 0 rows affected (0.00 sec)
           
           savepoint aa; --设置保存点aa 
           Query OK, 0 rows affected (0.00 sec)
           
           insert into account values(1, '张三', 10); --添加一条记录 
           Query OK, 1 row affected (0.00 sec)
           
           savepoint bb; -- 设置保存点bb 
           Query OK, 0 rows affected (0.00 sec) 
           
           insert into account values(2, '李四', 10000); --再添加一条记录 
           Query OK, 1 row affected (0.00 sec)
           
           select * from account; --两条记录都在了 
          +----+--------+----------+ 
          | id | name   | balance  | 
          +----+--------+----------+ 
          |  1 | 张三   |    10.00 |
          |  2 | 李四   | 10000.00 | 
          +----+--------+----------+ 
          2 rows in set (0.00 sec)
          rollback to bb; -- 发现后来添加这一条记录是误操作。所以回滚到bb状态 
          Query OK, 0 rows affected (0.01 sec)
          
          select * from account; -- 第二条记录没有了
          +----+--------+---------+ 
          | id | name   | balance | 
          +----+--------+---------+ 
          |  1 | 张三   |   10.00 |
          +----+--------+---------+
          1 row in set (0.03 sec)
          
      二、注意事项:
        如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是还没有提交) 
        如果一个事务被提交了(commit),则不可以回退(rollback)
        可以选择回退到哪个保存点 
        InnoDB支持事务,MyISAM不支持事务 
        开始事务可以使 start transaction 
     三、事务的隔离级别:
        当MySQL表被多个线程或者客户端开启各自事务操作数据库中的数据时,MySQL提供了一种机制,可以让不同的事务在操作数据时,具有隔离性。
        
        无隔离性的问题 
          脏读:
             指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务 也访问这个数据,然后使用了这个数据。
          不可重复读:(重点在修改,更新)
             第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。
             这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)
             解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题(程序中规避比较困难)
          幻读:(重点在新增和删除)
             指当事务不是独立执行时发生的一种现象。                
             如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中 的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发 生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
              解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题(程序中规避比较困难)
        事务的隔离级别:(4种)——一般以修改
          1、读未提交(read uncommitted):    不加锁,效率高,但不能解决脏读,不可重复读,幻读。
          2、读已提交(read committed):不加锁,可解决脏读,但不能解决不可重读和幻读;
          3、可重复读(repeatable read):不加锁,可解决脏读、不可重读、幻读。(默认)
          4、可串行化(serializable)    :枷锁,可解决脏读、不可重读、幻读。(等待一个事务结束才会执行另一个事务)
           设置事务的隔离级别:
             set session transaction isolation level read uncommitted    
           查看当前的隔离级别:
             select @@tx_isolation;
        事务的特性:(ACID)
             原子性(atomicity):不可分割的单元,要么不发生,要么都发生;
             一致性(Consistency):事务内部必须保证状态一致,无论是否存在并发。
             隔离性(Isolation):多个事务具有独立性;
             持久性(Durability):指一个事务一旦被提交,它对数据库中的数据的修改就是永久性的。