SQL事务锁

保持数据库的纯粹性:完整性约束实际用不到,存储过程也不用。更新丢失也是程序员控制。

 

事务的四个条件ACID:

        Autmic: 原子性,事务中的全部操作在数据库中是不可分割的,要么不做,要么全做!

        Consistency: 一致性,在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。转账。

                用户事务角度:(除了当前事务)其他任何事务看到的数据都是一样的。

事务A:begin;update...;select的结果是更新的,不是更新前。但别的事务看到是更新前的。

        Isolation:

                 一个事务的执行不受其他并发执行的事务的影响。

 

                 T2查看数据时,不能查看到中间状态的数据,要么是T1修改它之前的状态,要么是T1修改它之后的状态。

        Durability: 事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。

 

ACID实现方式,主要有两种:Write ahead logging,日志方式。第二种是Shadow paging。

                  

 

数据不一致性:

        1、丢失数据更新:T1,T2同时更新一条记录R,T1更新Col2时会把所有的列set(不然需要对比new,old两个对象,代价更高)

        T2更新Col3时也会set所有列,覆盖了T1的操作。应该在T1事务结束后再开始T2。

        2、脏读:事务2读到了事务1修改后的数据(这个数据可能被回滚,也可能被提交) 。

        3、不可重复读:一个事务范围内两个相同的查询却返回了不同数据。

        4、幻读:T1对表中所有行修改,T2插入/删除一行,T1发现还有未修改的数据。解决方法:增加范围锁RangeS。

 

事务隔离级别:

        Read Uncommited(0) : 可以读脏数据

        Read Commited(1)(Oracle默认):避免脏读,但可以出现不可重复读和幻读

        Repeatable Read(2)(MysqL默认):避免脏读,不可重复读,允许幻像读

        Serialiazble(3):序列化读

 

乐观锁--悲观锁

        mysql,支持for update,不支持 for update nowait

        show engines;        //查询支持的引擎,默认为InnoDB

        show variables like '%storage_engine%';        //查询当前引擎

        show variables        //查询mysql系统变量

        show create table user;        //查询mysql建表语句(处理过,真正执行的,包含一些默认值,比如ENGINE=InnoDB)

 

        悲观锁使用for update;实现,用于冲突多时 

                mysql,支持for update,不支持 for update nowait

                打开两个cli: c1,c2

                c1,

                begin;        //如果不打开事务,都不阻塞

                select * from user1 for update;

                c2,

                select * from user1 for update;阻塞至c1-commit

                select * from user1;不阻塞

                insert into user1(name) values('ok9');阻塞至c1-commit

        

        乐观锁使用version实现(每次提交自增一次)适用于冲突少的情况。

                嵌套子查询?        //是原子操作吗?

                check约束?

                如何实现?

 

行锁,表锁

        select for update必须在一个事务中(begin;...;commit;),才能起作用

        主键明确时,row lock

        select * from user1 where (id=11 or id=12) for update;        

        阻塞

        update user1 set name='kkk' where id=11;        

        select * from user1 where (id=11 or id=12) for update;        

        for update/在事务中,两个缺一,select都不会阻塞

        主键不明确是,table lock

        

数据库约束:  

数据完整性:指数据的正确性和一致性,主要有两种方式:

        1、定义表时定义完整性约束,约束分为两类:行级和表级。行级约束放在列后,表级约束放在表后,多个列共用的约束放在表后。

        2、也可以通过规则,索引,触发器等。

        3、完整性约束是一种规则,存在数据字典中,在执行SQL时。用户可以指明约束是启用的还是禁用的,启用约束会增强数据的完整性。

数据库完整性约束

比如字段A=字段B+字段C,否则insert失败。

constraint约束类型,五种:

        UNIQUE和Primary Key, Foreign Key, CHECK, NOT NULL, DEFAULT      

猜你喜欢

转载自luckywnj.iteye.com/blog/2035623