事务处理及锁定

来源:互联网 发布:kdj算法 编辑:程序博客网 时间:2024/05/16 08:54

摘自《MYSQL高效编程》,根据自身需要,将一些重要的知识总结致此。

Mysql 存储引擎:

  默认高速存储引擎为MyISAM,不支持事务处理。如果要使用事务处理功能,必须将表设置为使用InnoDB引擎。

  具体如何设置为InnoDB引擎

CREATE TABLE sys_users (  `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键',  `user_num` VARCHAR(50) NOT NULL COMMENT '用户编号',  `password` VARCHAR(200) NOT NULL COMMENT '密码',  `telephone` VARCHAR(50) COMMENT '电话号码',  `true_name` VARCHAR(50) NOT NULL COMMENT '真实姓名',  `card_num` VARCHAR(50) NOT NULL COMMENT '身份证号码',  `user_type` TINYINT UNSIGNED NOT NULL COMMENT '用户类型',  `modify_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',  `add_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间') ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT '用户信息表';

锁的种类

  1. 读锁:共享锁,在锁定的时候,其他访问只读锁定。

  2. 写锁: 写入锁,独占锁,在使用INSERT,UPDATE,DELETE时进行的锁定。

锁的粒度

锁定对象的大小的单位被称为锁的粒度。

  • 记录(行)

  • 数据库

      锁粒度大小影响同时运行的进程数量,一般来说锁的粒度越小同时运行性比较高,但是这并不意味着,锁粒度越小越好,因为一个个锁定还是要消耗数据库资源。锁定的数目越多消耗的服务器资源也会越多。

      当数据库中行单位粒度的锁定大量发生的时候,数据库有将这些锁定的粒度自动提升一个粒度的机制,这种机制称为:”锁定提升(Lock Escalation)“。

死锁现象的产生

  两个不同的事务处理在相互等待对方释放锁定。但是永远也不可能解除锁定的一种状态。

比如事务A 申请到a锁,还需要b锁,事务B申请到b锁,还需要a锁。此时,双方都因为不能获得足够的锁而使双方都产生等待。这种的情况产生死锁。

如果检测到死锁,解决办法:

  • 解除其中一方的锁定,并执行rollback回滚操作。就是使一方运行,一方回滚的操作。大多数数据库都是这样做的。

  • 可以尽量减少锁持有的时间,长时间拥有锁会减少同时运行性和导致死锁现象的发生。

事务处理的问题

  一般情况而言,不可重复读和幻读是允许的。Mysql默认允许不可重复读和幻读。对于上面3个的允许程度,提出4个事务处理隔离级别。READ UNCOMMITTED ,READ COMMITTED,REPEATABLE READ,SERIALIZABLE其中最后一个隔离线最高,大部分的不需要此类隔离级别,隔离级别高会导致同时运行性降低。

脏读(Dirty Read)

  事务A读取了事务B未提交的数据,并在这个基础上又做了其他的操作。(这一条是坚决抵制的)

不可重复读(Unrepeatable Read)

  事务A读取了事务B已提交的更改数据。在某一次事务处理的时候对同一数据进行多次读取,在此期间由于其他事务处理的更新操作使得读取的数据状态发生了改变。脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

幻读(Phantom Read)

  事务A读取了事务B已提交的新增数据。在某一事务处理中对同一数据进行多次读取,在此期间由于其他事务处理中进行了记录的插入/删除操作,使得结果中第一次读取时不存在的数据/或数据消失的情况。

事务处理的运行机制

通过了解事务处理的运行机制,可以更好地运用数据库。

简单来说就是留下更新日志,数据库会根据这些日志信息,在必要的时候根据日志将旧信息取回,或者在错误发生时将数据恢复到之前的状态。

与事务相关的日志有2个,一个是UNDO日志,另一个是REDO日志。

UNDO日志

  UNDO日志又称为:“回滚段”,意思就是在进行数据插入,更新,删除操作之前,保存数据变更前的数据。
即在原表的内容中保存了指向UNDO日志的指针,在ROLLBACK时,根据这个指针来获得旧数据,并覆盖新数据。ROLLBACk或者COMMIT以后会将UNDO日志删除。

REDO日志

  REDO日志根据数据库的不同,可能被称为事务处理日志或者日志。事务处理确定后,由于错误的原因使数据的更新还没有显示到数据库上,REDO提供了数据恢复用的手段。

  “更新”的过程是一个复杂的过程,首先在缓存(BUFFER CASH)中的内存空间进行数据更新,并将数据存放在UNDO日志中,在向数据库写入的时候是有延时的,写入动作的触发点称为Check Point(按照一定的周期触发,集中处理,减少磁盘的访问次数,利于性能的改善)。

  问题出现在REDO日志与更新数据文件之间的延迟上,如果在这个延迟的时候断电,显然内存中的信息消失,只剩下保存在REDO日志文件中的信息。REDO文件正是用于复原的。数据库在排错后的第一步就是根据REDO日志前滚,Roll forward。具体的做法就是从REDO日志中查找到最后检查点和错误发生时间点间的事务处理,然后重新执行一次REDO,这样数据就恢复到错误之前的状态了。

0 0
原创粉丝点击