赞
踩
在买票的时候,当A检查到还有一张票,将票卖掉,此时,数据库还没有更新,客户端B检查了票数,发现大于0,于是又卖了一张票,然后A将票数更新了,发现一张票被卖了两次
CURD满足的属性
[Transaction]
事务本质就是一组SQL语句,理论上,事务本就不应该属于MySQL,而是应该在应用层上面,完成的一件事情,完成一系列相关操作的sql语句集合叫做事务
假如说你从学校毕业了,那么学校教务系统,后台的MySQL中就不需要你的信息了,那么管理员会运行几条sql命令来输出你的(姓名,电话,籍贯等信息),同时还有一些sql操作输出你的成绩,这些操作组合起来,就构成了一个"事务"
事务=原子性的操作多条的sql语句
再比如:
张三给李四转账200
张三的账户余额update减少200,李四的账户余额update增加200,在数据库角度是执行两条sql
所有的sql操作,一般都会被mysql包装成事务,无论是一条还是多条的sql,都是一样的对待的
一个完整的事务,绝不是简单的sql集合,还必须要满足4条属性ACID
执行一条sql,要么全部都执行完,要么全部不完成,而一旦事务在执行的时候出现了错误,就回滚(rollback),到事务开始前的状态,前面成功的sql也取消掉,就像这个事情没有发生过一样
事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。
比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱
允许多个事务同时处理任务的时候,不影响别人
数据库把数据更新完,数据的修改必须是持久的,不会因为系统故障而丢失
事务是被MySQL设计出来,为了当应用程序访问数据库的时候,事务可以简化我们的编程模型,不需要我们去考虑各种并发各种潜在错误,
所以当我们去使用事务的时候,要么提交,要么回滚,不会考虑网络中断的问题,
我们后面就把MySQL里面的一行信息称为一行记录
MySQL只有innodb支持事务,mysiam不支持事务,这就是我们使用innodb的原因,mysiam适合查询检索retrieve
事务的提交有两种:
show variables like 'autocommit';
设置为手动提交
set autocommit=0;
设置MySQL的隔离级别设置为未提交,
set global transaction isolation level read uncommitted;
查看隔离级别
select @@tx_isolation;
处于R级别
创建一个account表
create table if not exists account ( id int primary key auto_increment, name varchar(50) not null, balance decimal(10,2) default 0.0 );
查看表结构
证明事务的开始和回滚
start transaction;
begin;
savepoint s1;
数据操作的一端查看数据
打开的另一个终端也查看数据
假如说,我们操作的一端后悔插入了赵六,因为我们设置了s2,所以我们可以回滚到s2处,这样就不需要我们去进行删除操作
rollback to s2;
在两个不同的终端查看都是一样的结果
rollback 后面什么都不带就是直接回滚到最开始的地方
rollback;
commit;
总结:
命令行启动事务
一方的MySQL关闭了,没有进行commit操作,另一个终端会直接回滚到事务开始前的状态
当命令行输入,手动启动(begin /start transaction)一个事务的时候,和MySQL中是否事务会自动提交无关
只要我们是begin,start transaction,就必须要我们进行手动提交
那么自动调教的设置,是给谁设置的呢
提交
我们把事务进行提交
提交在崩溃,事务就不会再回滚了,这个就叫做事务的持久性
其实我们之前的所有单条sql,本质上再mys ql里面,全部各自会以事务的方式进行提交,自动提交
我们写的4,5条sql,实际上应该是4,5个事务
事务操作的注意事项
- 如果一个事务已经被提交了,就不能再回滚了
你妈让你好好学习,要么别学,要么学最好,中间怎么努力学习,你妈不关心,你的学习对于你妈妈来说就是原子的,
隔离级别
我们在一个终端,启动事务,插入数据,没有提交
在另一个终端里面查看,是可以查看到的
这个隔离级别相当于没有任何隔离性,会出现别人读到脏数据,别人修改数据也会影响你
会出现脏读
select @global.tx_isolation;
select @session.tx_isolation;
set global transaction isolation level Repeatable Read;
set session transaction isolation level Repeatable Read;
读提交,这里我们会发现一方修改的数据,另一个不受影响,读不到对方未提交的数据
但是此时当前是事务未commit,在同一个事务内,同样的读取,在不同的时间段,读到不同的值,这种现象就叫做不可重复读问题
不可重复读,存在问题
- 读提交,你一提交,别人能读到!=你已提交,和你并行运行的事务也能读到(并行发事务不应该读到,一开始读到什么数据,之后都要读到什么数据)
- 不可重复读有什么问题-------应用层有什么问题呢
给一个用户会被触发多次sql
不可重复读,就是两个同时启动的事务,一方改变了数据,commit之后,但是另一方还在事务中,读到的数据,就是已经commit上去之后的
MySQL对于insert也能处理RR(幻读)
变成单进程,效率非常低,指的是事务之间的串行化,不是mysql里面sql语句的串行化,把事务进行排队
MySQL的内部机制,让“同时”启动,并发执行的事务,看到不同的数据(增删改),能不能看到,就叫做隔离性
我们作为一个事务,可以看到不同可见性的数据,程度不同,叫做隔离级别
为何要存在隔离级别
为了安全,不需要各自种类繁多的隔离级别,无脑串行化最安全
不仅仅是为了考虑安全问题,有可能就不考虑安全问题,
在安全和效率之间,寻找平衡点,也不需要各种种类繁多的隔离级别
这个平衡点不是MySQL来决定的,而是由我们来决定的
持久性,原子性,隔离性共同组成了一致性
需要由用户和MySQL共同决定
是事务维护的最终目标
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。