数据库事务的四大特征、自动/手动提交、事务的隔离级别

什么是事务?

事务:被事务修饰的一系列的操作看成‘一个操作’,这些操作要么同时成功,要么同时失败。

  • eg:德玛西亚给拉克丝转500元钱:
    1.德玛西亚的余额减500
    2.拉克丝的余额加500
    分析
    但如果在一、二部之间出错了,那么第一步就会成功而第二部不会成功,那这500元钱不就没了嘛,显然这样不现实,这种情况下用事务就很合适.

  • 在实现代码前,我们先学习几个sql语句:
    1.开启一个事务-------START TRANSACTION;
    2.回滚-----------------ROLLBACK;
    解释:回到START TRANSACTION语句之前的状态。
    3.提交(结束事务)--------COMMIT;

首先我们来看一下表原本的样子:
在这里插入图片描述

START TRANSACTION; -- 开启一个事务

UPDATE USES SET BALANCE = BALANCE - 500 WHERE USES.`NAME` = '德玛西亚';
啦啦啦
UPDATE USES SET BALANCE = BALANCE + 500 WHERE USES.`NAME` = '拉克丝'; 

执行上面三行代码后,再次查询表:
在这里插入图片描述
中间有不明中文,所以后面的sql语句没有执行。这个改变只是暂时的,它其实并没有变,当我们关闭这个窗口、或者我们再开启一个窗口查询,它的结果还是两人余额都是1000。我们看一个这个临时/暂时的数据,如果出错了,我们只要rollback即可”回滚“
回滚后(只执行rollback这一行代码)
在这里插入图片描述

如果发现临时的数据没有出错,那么执行commit即可,永久的将数据改变了。

COMMIT;

自动提交和手动提交

  • 1.在mysql数据库中事务默认自动提交,而oracle数据库默认是手动提交的。
    就是说:如果我们不手动的开启事务的话,一条DML语句(增删改,UPDATE)是自动提交的。
  • 2.查看、修改自动提交
    2.1 查看
SELECT @@AUTOCOMMIT; -- 查询是否默认自动提交;

如果结果是1,那么就是默认自动提交;0则为手动提交。
2.2修改

SET @@AUTOCOMMIT = 0; -- 修改为手动提交

事务的四大特征(这个很重要)

  • 1.原子性:事务是不可分割的最小操作单元,要么同时成功,要么同时失败。
  • 2.持久性:事务一旦回滚/提交后会持久的改变(无论是电脑关机等……都不会改变)
  • 3.隔离性:多个事务之间,互相独立,减少影响。
  • 4.一致性:事务执行前后,数据总量不变。eg:上面赚钱的例子,不管怎么赚钱,二者的钱数总量是不变的。

事务的隔离级别(了解即可)

多个事务同时操作一批数据,就会产生一些问题,而设置不同的隔离级别,就可以解决这些问题。(它很像Java中Thread安全的问题)

存在的问题:
  • 1.脏读:一个事务读取到另一个事务还没有提交的数据。
  • 2.虚读(不可重复读):在同一个事务里读取两次数据,这两次数据不一样。
  • 3.幻读:一个事务操作(DML)表中所有事务,另一个事务增加了一条记录,那么前一个事务就会查询不到自己的修改
隔离级别:
  • 1.READ UNCOMMITED;(读未提交)
    存在的问题:脏读,虚读,幻读。
  • 2.READ COMMITED;(读已提交)(oracle默认隔离级别)
    存在的问题:虚读,幻读
  • 3.REAPEATABLE READ;(可重复读)(mysql默认隔离级别)
    存在的问题:幻读
  • 4.SERIALIZABLE;(冲行化)
    SERIALIZABLE可以解决以上所有问题。
  • 但是注意,以上解决方法,从上到下虽然越来越安全,但是效率却越来越低。(要不然就全用最后一个得了呗)
  • 查看隔离级别:SELECT @@TX_ISOLATION;
  • 修改隔离级别:SET GLOBAL TRANSACTION ISOLATION LEVEL + 隔离等级;
隔离级别解释:
首先我们同时开两个cmd窗口,分别登录mysql。使用同一张表,两个都开启事务。
  • 脏读:如果数据库隔离级别在READ UNCOMMITED,第一个cmd窗口修改某一列的数据,那么第二个窗口查询这个数据,查出来的就会是第一张表修改的数据(注意:第一张表的事务没有结束/提交!那如果第一张表的数据只是暂时的,一会就变了呢?)。对于这种情况(就叫脏读),我们只要把数据库的隔离级别改为READ COMMITED即可,也就是如果第一个事务没有提交,那么第二个cmd窗口就不会查询到(未提交的)修改的数据。
  • 虚读:接着上一个的说下一个问题,现在不会再出现一个事务查询到另一个事务未提交的数据了。但是这个查询的食物可能两次查询的结果不一样。eg:另一个事务提交了,这个情况就叫虚读。同样我们只要再次设置隔离级别为REPEATABLE READ即可。尽管数据变了,也不会出现一个事务内查询到的结果是不同的了,只有这个查询的事务提交了,在次查询才会发生变化。
  • 幻读的情况在mysql数据库中演示不出来,这里就不再演示了)
  • SERIALIZABLE 这个就和Java线程安全问题中那个同步锁机制很像了。就是有一个锁,把这个表锁上了,在同一时间内,如果拿到了这个使用权力,不提交的话,别人永远也使用不了。别人就会一个处于堵塞状态,在等待。
  • 一般我们不会去修改数据库的隔离等级,但可能有些特殊的需求,会根据不同的需求来用不同的隔离等级。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值