58数据库3_transaction
成都创新互联公司服务项目包括邗江网站建设、邗江网站制作、邗江网页制作以及邗江网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,邗江网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到邗江省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
transaction:
事务,由若干条语句组成的,指要做的一系列操作;
InnoDB引擎,支持事务;
ACID:
atomicity,一个事务是一个不可分割的工作单位,事务中包括的所有操作要么全部做完,要做什么都不做;
consistency,事务必须是使数据库从一个一致性状态变成另一个一致性状态,一致性和原子性是密切相关的;
isolation,一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据对并发的其它事务是隔离的,并发执行的各个事务之间不能互相干扰;
durability,持久性也称永久性permanence,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,接下来的其它操作或故障不应该对其有任何影响;
注:
atomicity要求事务中的所有操作,不可分割,不能做了一部分操作,还剩一部分操作;
consistency,多个事务并行执行的结果,应该和事务排队执行的结果一致,如果事务的并行执行和多线程读写共享资源一样不可预期,就不能保证一致性;
isolation,指多个事务访问共同的数据了,应该互不干扰,隔离性指究竟在一个事务处理期间,其它事务能不能访问的问题;
durability,事务提交后,数据不能丢失;
隔离性不好,带来的问题:
1、lost update更新丢失:
不允许事务A和事务B并行;
例,事务A和事务B,更新同一个数据,它们都读取了初始值100,A要减10,B要加100,A减去10后更新为90,B加100更新为200,A的更新丢失了;
2、dirty read脏读:
只用于展示可以,用于计算可以;
事务B读到了事务A未提交的数据,这个数据可能是一个中间值,也可能事务A之后回滚事务,事务A是否最后提交并不关心,只要读到了这个被修改的数据就是脏读,隔离不好,读到了未提交的数据(中间状态值);
3、unrepeatable read不可重复读:
允许后一次可读到正确的内容;
不能保证同一条查询语句重复读相同的结果,就是不可重复读;
例,事务A在同一事务中执行相同查询语句(先后查询了2次),得到了不同的结果(不能重复的获取相同数据);
例,事务A在查询了一次后,事务B修改了数据,事务A又查询一次,发现数据不一致了;没说提交;
注:脏读是可以读到相同数据的,但读取的是一个未提交的数据,不是提交的最终结果;
4、phantom read幻读:
例,事务A中同一个查询要进行多次,事务B插入数据,导致事务A返回了不同的结果集,如同幻觉;
数据集有记录增加了,可以看作是增加了记录的不可重复读;
有以上问题,数据库必须要解决,解决办法:1、隔离级别;2、加锁;
隔离级别
由低到高,依次为:
read uncommitted,读取到未提交数据,读不受约束;
read commited,读已经提交的数据,oralce默认;
repeabable read,可以重复读,MySQL默认,解决不可重复读;
serializable,串行化,事务间完全隔离,不能并发只能串行,解决了所有问题;
隔离级别越高,串行化越高,数据库执行效率越低,当前事务处理的中间结果对其它事务不可见程度越高;
隔离级别越低,并行度越高,性能越高;
会话级别|全局级别:
>set [session|global] transaction isolation level LEVEL; #生产中慎用global
>select @@global.tx_isolation;
>select @@tx_isolation;
>set session transaction isolation level read committed;
serializable,串行了,解决所有问题;
repeatable read:
事务A中同一条查询语句返回同样的结果,就是可以重复读数据了,解决办法有:
1、对select的数据加锁,不允许其它事务有删除、修改操作,如for update;
2、第一次select时,对最后一次确切提交的事务的结果的快照;
以上解决了不可重复读,但有可能出现幻读;
read committed:
在事务中,每次select可以读到别的事务刚提交成功的新的数据,因为读到的是提交后的数据,解决了脏读,但不能解决不可重复读的问题;
read uncommitted:
能读取到别的事务还没提交的数据,完全没有隔离性可言,出现了脏读;
事务语法:
>start transaction #或>begin开始一个事务,>start transaction是标准sql语法;
>commit #提交事务后,变更成为永久变更;
>rollback #可在提交事务之前,回滚变更,事务中的操作就如同没有发生过一样;
>set autocommit=0 #默认autocommit模式,可禁用或启用,用于当前连接,出错也可自动回滚,0禁用自动提交事务,如果开启自动提交,若有一个修改表的语句,执行后会立即把更新存储到磁盘;开发时一般会关掉此项,性能问题,是一批批的提交,而不是一句句的提交;
数据仓库和数据库的区别:
本质上来说没有区别,都是存放数据的地方;
数据库支持在线业务,需要频繁增删改查;数据仓库一般囤积历史数据支持用于分析的SQL,一般不建议删改;
数据库关注数据的持久化、数据的关系,为业务系统提供支持、事务支持;
OLTP,在线交易数据,数据库;
数据仓库,存储的数据是为了分析或者发掘而设计的表结构,可以存储海量数据;
数据仓库存储历史数据用于分析OLAP;
其它概念:
cursor游标:
操作查询的结果集的一种方法;
可将游标当作一个指针,指向结果集中的某一行;
stored procedure存储过程、trigger触发器:
这两种技术是DB的高级内容,但基本很少用了,逻辑前移,BS|CS放在B或C上了;
stored procedure,数据库系统中,一段完成特定功能的SQL语句,编写成类似函数的方式,可以传参并调用,支持流程控制语句;
trigger,由事件触发的特殊的存储过程,如Insert数据时触发;trigger功能虽强大,但会有性能问题;
例:
mysql> set autocommit=0;
mysql> show variables like 'autocommit';
mysql> show variables like 'tx_isolation';
mysql> select * from t;
mysql> set session transaction isolation level read committed;
注:
set autocommit=0;关闭自动提交;
两个窗口均默认级别REPEATABLE-READ,
A端update t set id=4 where id=2,
A端未commit,A端查询是改变后的状态,B端查询没变化,
A端commit后,A端查询是改变后的状态,B端查询没变化,
B端commit后,B端查询是改变后的状态;
两个窗口用READ-COMMITTED,>set session transaction isolation level read committed;
A端insert into t values(6,'ftp',28);,
A端未commit,A端查询是改变后的状态,B端查询没变化;
A端commit,A端查询是改变后的状态,B端查询是改变后的状态;
mysql> select * from t for update; #InnoDB是行级锁,此句相当于表级锁;使用时,用几行加几行锁,且加锁时间越短越好
mysql> commit; #未commit,其它窗口的mysql> update t set id=5 where id=6;更新语句会卡住
分享文章:58数据库3_transaction
URL分享:http://pwwzsj.com/article/iipcse.html