并发控制:
    MVCC 多版本并发控制。
        用户在操作时操作的是带有时间点的快照。而不是表本身。最后将快照进行合并。

锁:
    读锁:共享锁。读取操作不会对用户之间产生影响。
    写锁:独占锁。一个用户写入时,其他用户就不能写入。
    可以手动设置:
        LOCK TABLES TBNAME [AS AILAS] LOCK_TYPE,... 给表加锁
            LOCK_TYPE
                READ 读锁
                WRITE 写锁

        UNLOCK TABLES 解除所有表的锁,注意不能指定TBNAME。

    锁力度:
        表锁:锁定整张表
        页锁:锁定页块,一个页块中包含多个行。
        行锁:锁定行

        mysql服务器仅支持表锁,行锁需要存储引擎支持。每个引擎对锁的策略都不同。

        力度越精细越能提高并发,越粗糙越能方便管理。

    实例:
        1.给tutors表创建读锁:
            mysql>LOCK TABLES tutors read;

        2.解锁:
            mysql>UNLOCK TABLES;

事务:
    事务就是将多个涉及到大量的cpu操作和io操作的多个操作看做一组。这样的组被称作事务。

    事务的流程:
        启动(START TANSACTION)-->写入撤销日志中 --> 执行操作(一堆SQL语句)|执行过程中断后根据撤销日志回滚(ROLLBACK)--> 写入重做日志中-->  根据重做日志进行磁盘操作 (提交COMMINT)

    多事务并发:
        例如进行io操作时cpu空闲,可以利用cpu进行新的事务,这是多事务并发的基本思想。但是多事务并发有可能造成事物之间进行交互。所以此时要使用隔离机制保证数据库的一致性。
        依赖的技术手段:
            锁
            时间戳
            多版本和快照隔离

    多事务交互:
        通过io产生的数据集,事务之间就可以进行交互。但是数据集是实时变动的。所以这种交互会产生不一致状态。在这种状态下,交互的结果可能产生差错

        脏读:
            一个事务未提交前,另一个事务进行读取操作。读操未提交的内容称为脏读。
        幻读:
            一个事务对某个表执行查询操作时,另一个事务对此表进行修改,会造成前后查询不一致。

    事务的状态:
        活动的:正在执行的。
        部分提交的:执行完成,但是最后一条语句正在提交中。
        失败的:执行完成,提交未能完成。
        终止的:执行过程中终止,未提交。
        提交的:执行完成,提交完成。
        锁饥饿:
        死锁:

        注意:事务一旦提交就无法撤销,只能通过补偿事务。

    事务调度:
        1.可恢复调度:
        2.无级联调度:

    保存点(SAVEPOINT):用于在事务中创建保存点,这样回滚的时候不会全部回滚,只回滚到保存点之前的所有状态。
        使用SAVEPOINT SPNAME创建保存点。
        使用ROLLBACK TO SPNAME回滚到保存点。



    支持事务要先支持ACID特性
    ACID特性:
        原子性(Automicity):一个事务当中的操作语句要么都执行完成,要么都不执行。

        一致性(Consistency):事务完成前和完成后,对数据库来说状态是没有改变的。一致性要在隔离状态下才能保证。

        隔离性(Isolation):若有2个事务同时执行,其中一个在提交钱前都不被另一个察觉到。即一个事务的中间过程不影响到其他操作。服务器使用事务调度(例如MVCC)来使事务间影响最小。

        持久性(Durability):一个事务提交后,即便服务器出现任何故障,也必须保证不引起事务出现不一致性。即事务的操作是持续有效的。
            实现手段:
                1.事务提交前已经将数据写入硬盘。要消耗大量的磁盘io。
                2.结合事务日志完成。使用的是顺序io而不是向数据文件那样使用随机io。速度非常快。


存储引擎对事务的支持:
    mysql中,是否支持事务,是根据存储引擎来定义的。
    MyISAM不支持事务。
    InnoDB支持事务。若不明确启动事务,默认autocommit是启动的,会自动提交。建议明确使用事务,并关闭自动提交。关闭后若不明确事务,则执行的所有操作都被看成在一个事务中。

事务日志:
    重做日志(redo log):
        每次操作都在内存中操作,并写入重做日志中记录。一旦操作完成则表示事务提交。一段时间后,根据日志内容将操作写入硬盘。

    撤销日志(undo log):
        保留每一次操作前的状态。以便恢复。

日志组:
    日志也是文件,文件中只记录操作,不记录对应的数据。
    多个日志文件构成日志组。
    日志文件是轮流使用。一个记录满以后自动记录到下个文件中。记录满的日志文件会将操作同步到硬盘。然后清空日志。

    日志文件的大小要根据具体需求定义。

    详细请参考日志相关。

事务隔离等级:
    为了解决多事务交互中出现的各种问题。采用此机制

    级别越高,安全性越好,并发能力越弱。

    READ-UNCOMMITED 读未提交。最低级别。一个事务执行完成后另一个事务马上能看到。此时前一个事务还未能提交。事务之间干扰最大。

    READ-COMMITTED 读提交。一个事务提交后才能看到。不提交其他事务看到的不变化。

    REPEATABLE-READ 可重读。一个事务无论提交与否,另一个事务在提交前看到的不变化,一旦该事务提交,则看到的是最终值。InnoDB默认级别为此。


    SERIALIZABLE 可串行。最高级别。可以同时启动多个事务,但一个时间内只能执行一个事务。另一个事务想要操作必须等前面的事务提交完毕后才行。

    mysql默认是REPEATABLE-READ。大多数SQL默认是READ-COMMITTED

    使用SHOW GOBAL VARIABLES LIKE ‘tx_isolation’查看。


分布式事务(XA):
    是一种高层次的事务,使用两段式方式(准备-提交 prepare-then-commit)将ACID属性扩展到存储引擎的外币,甚至是数据库外部。

    准备阶段:
        事务协调员同时所有参与者准备提交事务

    提交阶段:
        事务协调员在收到所有参与者发出的就绪信息是,会指示所有参与者进行真正的提交操作。

    默认InnoDB是启用分布式事务的,使用SHOW GLOBAL VARIABLES LIKE ‘innodb_support_xa’查看



实例:
    1.启动一个事务:
        mysql>START TRANSACTION;

        启动后的操作都被认为是事务中的操作

    2.执行操作:
        mysql> DELETE FROM students WHERE Name LIKE 'stu%';

    3.完成操作后提交:
        mysql>COMMIT;

        注意:一旦提交将不能回滚。

    4.或者是回滚:
        mysql>ROLLBACK;

    5.修改服务器设置,禁用自动提交
        mysql默认是启动自动提交的,即执行操作后马上提交,这样会占用大量的磁盘io,降低性能。

        mysql> SELECT @@autocommit;
        mysql> SET autocommit=0;

    6.创建保存点:
        使用
        mysql>SAVEPOINT abc;

    7.回滚到某个保存点:
        mysql>ROLLBACK TO abc;

    8.查看当前的隔离级别:
        mysql>SELECT @@tx_isolation;

    9.修改当前会话隔离级别:
        mysql>SET tx_isolation=‘LEVEL’;

    10.修改全局隔离级别:
        #vim /etc/my.cnf
            [mysqld]
            ...
            transaction-isolation = LEVEL