首页 > 其他分享 >19)事务

19)事务

时间:2023-06-02 22:22:05浏览次数:26  
标签:事务 19 account 回滚 int 终端 提交 balance

1、 事务的必要性:

先来看一个例子,如下有一张账户表,字段包括账户号作为主键、账户名字、账户余额三个字段;

先向其中插入两行数据;

-- 先创建一个账户表:
create table account(
    account_no int auto_increment primary key,
    account_name char(10) not null,
    balance int unsigned
);
insert into account values(null,'甲',1000),(null,'乙',1000);

结果如下:

接着,我们创建一个存储过程,用于账户1向账户2转账:执行一次存储过程;

delimiter $$
create procedure transfer(in from_account int, in to_account int,in money int)
begin
    update account set balance=balance+money where account_no=to_account;
    update account set balance=balance-money where account_no=from_account;
end;
$$
delimiter ;
call transfer(1,2,800);
select * from account;

 接着我们继续执行一次,还是1向2转账800;结果如下:

 可以看到执行语句报错,但是执行的结果就是账户2的余额依然增加了800;账户1 的余额没有边,报溢出错误1690;这时银行会亏损这800;

原因如下:

MySQL默认自动提交,执行完语句后,就会对磁盘上的数据进行增删改查操作;

 

2、关闭MySQL自动提交

查看是否开启自动提交操作:

show variables like 'autocommit';

关闭自动提交的方法:下面两种方法只对当前会话有效;

1)显示

set autocommit=0;

2)隐式

start transaction;

隐式的关闭自动提交不会修改系统会话变量@@autocommit的值;

 

3、回滚

关闭自动提交后,把当前没有提交的操作进行撤销;语法为:

rollback;

我们上述关闭自动提交的基础上,进行一次更新操作;然后另打开一个终端,连接数据库,查看该 account 表中内容;

在当前终端执行update后,可以看到当前终端下,表内容已经是更新后的值;

但是在另一个终端里,表内容还是尚未执行 update 语句的值,就是因为关闭了自动提交,上述只是更新,没有提交;

 然后我们可以在更新语句的终端里执行回滚操作,回退到之前的内容;

 

4、手动提交

1)显示提交:

commit;

2)隐式提交:

begin、set account = 1、start transaction、rename table、truncate等语句、ddl、dcl、锁语句等;

这里测试同上,一个终端提交,另一个终端里查看;

 

5、事务

1)直接全部回滚

先将之前创建的存储过程删掉;然后创建一个包含有捕获错误的错误处理代码的存储过程;对应的MySQL错误处理代码是1690;对应的错误处理程序是全部回滚;

完整的事务代码如下:

drop procedure transfer;
delimiter $$
create procedure transfer(in from_account int, in to_account int, in money int)
begin
    declare continue handler for 1690
    begin
     rollback;
    end;
    update account set balance=balance+money where account_no=to_account;
    update account set balance=balance-money where account_no=from_account;
    commit;
end;
$$
delimiter ;

 测试如下:可以看到都不会增加;

 2)部分回滚--保存点

可以回滚到保存点名的地方;实现部分提交,部分回滚;语法格式:

savepoint 保存点名;

我们考虑实现一个存储过程:插入两行数据,第二行数据是第一行的account_no;肯定会发生违反主键唯一约束的错误;但是我们要实现第一行数据提交,第二行回滚;

代码如下:

delimiter $$
create procedure savepoint1_proc()
begin
    declare continue handler for 1062
    begin
     rollback to B;
    end;
    start transaction;
    insert into account values(null,'丙',1000);
    savepoint B;
    insert into account values(last_insert_id(),'丁',1000);
    commit;
end;
$$
delimiter ;

测试:

可以发现,执行存储过程,只增加了第一行数据;

 

总结:

6、事务的ACID特性:

说明:

隔离性测试:

打开两个终端,连接数据库,并将自动提交关闭;在上述account的表的基础上,一个终端执行更新操作,但是不提交,另一个终端查看表中的内容,接着也进行更新操作,发现并不会立即得出结果;当第一个终端执行提交命令后,可以看到第二个终端的更新语句才执行完毕;这就是隔离性;

 这是第一个终端:

 这是第二个终端:可以看到光标一直在闪烁等待;

 当第一个终端执行commit时,

第二个才执行完毕;可能会提前超时退出,可以在输入一次更新验证;同时我们发现第二个终端里执行的更新,第一个也没有同步,就是因为第二个终端没有执行提交;

 

标签:事务,19,account,回滚,int,终端,提交,balance
From: https://www.cnblogs.com/xuan01/p/17452899.html

相关文章

  • 5.19 面向对象案例分析一
    classAddress{privateStringcountry;privateStringprovince;privateStringcity;privateStringstreet;privateStringzipcode;publicAddress(){}publicAddress(Stringcountry,Stringprovince,Stringcity,Stringstr......
  • 2014.4.19.12.27_switch_8.28_java switch语句使用注意的四大细节_0.01
    javaswitch语句使用注意的四大细节很多朋友在使用javaswitch语句时,可能没有注意到一些细节,本文将详细介绍使用javaswitch语句四大要点,需要的朋友可以参考下。switch语句的格式如下:(它的功能是选出一段代码执行)switch(整数选择因子){case整数值1:语句;break;case整数值......
  • 事务的特性和简介
    1.原子性:要么都成功,要么都失败2.一致性:事务前后的数据完整性要保证一致3.持久性:事务一旦提交则不可逆,被持久到数据库中4.隔离性:多个用户并发访问数据库时,数据库为每一个用户开启事务,不能被其他事务的操作所干扰,事务之间相互隔离事务不隔离会导致的问题:脏读:一个事务读取到另外......
  • [极客大挑战 2019]EasySQL1 做题笔记
     看标题是EasySQL,简单SQL注入,想来不会特别难先尝试输入admin123456发现账号和密码都错误那就尝试传说中的万能密码 1'or'1'='1'# 输入的时候记得切换为英文输入法 出现flag......
  • 项目访问的端口是8018,但是真实接口地址是19080,导致访问这个地址http://9.6.237.104:80
    这个问题是由于您的前端页面与后端应用程序的接口地址不在同一个域名下所引起的跨域请求。在浏览器中,出于安全考虑,通常不允许JavaScript从一个域名下访问另一个不同域名下的资源,这种行为被称为跨域请求(Cross-OriginResourceSharing,CORS)。有一些方法可以解决跨域问题,下面是......
  • ORA-01031: TT15019
     手工编辑sys.odbc.ini尝试修改参数PermSize,重新连接报如下错误Command>connect"dsn=sampledb;uid=hxl;pwd=oracle";cx_Oracle.DatabaseError:ORA-01031:TT15019:OnlytheinstanceadminmayalterthePermSizeattribute解决办法:./ttisql"Driver=/opt/tt18.1.4.34.0......
  • 导入keras报错Process finished with exit code -1073741819 (0xC0000005)
    1. 遇到报错问题导入keras报错Processfinishedwithexitcode-1073741819(0xC0000005) 查看chatgpt后,给出的解答如下:2.  tensorflow与keras兼容问题关于版本兼容问题,以下是chatGPT3.5给的答案,具体更多兼容版本对应关系可以查看文章末尾的链接。 3.......
  • Spring事务在哪些情况下失效
    阅读文本大概需要3分钟。0x01:如果数据库不支持事务,则失效   因为事务是作用于数据库。例如使用MySQL且引擎是MyISAM,则事务会不起作用,因为MyISAM引擎本身不支持事务;如果改成InnoDB,则可以。0x02:Service类没有被Spring管理    因为Spring的事务是基于AOP,所以如果Service......
  • npm安装淘宝镜像cnpm报错:npm ERR! Windows_NT 10.0.19045
    1、报错信息如下:npmERR!Windows_NT10.0.19045...2、原因,环境没配好3、解决:配置环境变量系统变量:①新建-变量名:NODE_HOME;变量值:D:\node-v14.18\nodeInstall\node-v14.18.2-win-x64node根目录下,新建两个目录,分别命名为:”node_global”、”node_cache”②path......
  • 2018-2019,盖个时间戳
    2019第一个工作日,连续第12年的个人小结,不为别人,只是写给自己。先回顾一下之前的小结:2007的写在msn的space上,可惜这个产品已经死了好几年了,也没留底;2008~2013的写在iamsujie.com上;2014年开始写在微信公众号里。它们的标题如下。2007总结 2008展望2008年小结,我想,我就从这里开始2010......