浅谈数据库事务

一、数据库事务定义

数据库事务是一组数据库操作,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。

二、事务的四大特性

1、原子性:事务是最小的执行单位,不允许分割。事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。例如转账的这两个关键操作(将张三的余额减少10元,将李四的余额增加10元)要么全部完成,要么全部失败。

2、 一致性: 确保从一个正确的状态转换到另外一个正确的状态,这就是一致性。例如转账业务中,将张三的余额减少10元,中间发生断电情况,李四的余额没有增加10元,这个就违反一致性。

3、隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。如张三在A事务中查询自己的账户余额,张三老婆在事务B查询张三账户余额的影响,满足了事务的隔离性。

4、持久性:对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。如张三向银行卡存进了300块钱,后续银行的数据库服务器宕机了,数据依然存在于数据库磁盘中。

三、并发事务产生的问题

        MySQL 服务端是允许多个客户端连接的,这意味着 MySQL 会出现同时处理多个事务的情况。在处理并发事务时会产生:脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题。

1、脏读:一个事务读到了另一个未提交事务修改过的数据。

举例:假设有 T1 和T2 这两个事务同时在处理,事务 T1先开始从数据库中读取A,然后再执行更新操作,如果此时事务 T1 还没有提交事务,而此时正好事务 T2 也从数据库中读取A,那么事务 T2读取到的A是刚才事务 T1更新后的数据,即使没有提交事务。

2、不可重复读:在一个事务内多次读取同一个数据,如果出现前后两次读到的数据不一样的情况。

举例:假设有 T1 和T2 这两个事务同时在处理,事务 T1先开始从数据库中读取A=19,事务T2同时开始读取A=20,然后T1再执行更新操作,此时A更新为19后提交事务,然后事务T2 再次从数据库中读取A=19,两次读取到的数据不一致。

3、幻读:在一个事务内多次查询某个符合查询条件的记录数量,如果出现前后两次查询到的记录数量不一样的情况。

举例:假设有 T1 和T2 这两个事务同时在处理,事务 T1先开始从数据库中读取表A中account大于100的记录数为5,此时事务T2向表A插入一套account为200的记录并提交事务,然后T1再查询表A中account大于100的记录数为6,事务T1中同样的查询记录数的sql语句得到了两个不同的结果。

四、数据库的隔离级别

        事务并发引起的问题与数据库的隔离性有关,在mysql数据库中有四大隔离级别:

1、读未提交(read uncommitted),指一个事务还没提交时,它做的变更就能被其他事务看到;

2、读提交(read committed),指一个事务提交之后,它做的变更才能被其他事务看到;

3、可重复读(repeatable read),指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别;

4、串行化(serializable );会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

事务并发在不同的隔离级别下产生不同的问题:

所以,要解决脏读现象,就要升级到读提交以上的隔离级别;要解决不可重复读现象,就要升级到可重复读的隔离级别。不过,要解决幻读现象不建议将隔离级别升级到串行化,因为这样会导致数据库在并发事务时性能很差。

同样的并发事务,在不同隔离级别下的数据体现:

 

在「读未提交」隔离级别下,事务 T2 修改余额后,虽然没有提交事务,但是此时的余额已经可以被事务 T1 看见了,于是事务 T1中余额 ACCOUNT1 查询的值是 50,余额 ACCOUNT2 、ACCOUNT3自然也是 50了;

在「读提交」隔离级别下,事务T2 修改余额后,因为没有提交事务,所以事务 T2 中余额 ACCOUNT1 的值还是 100 ,等事务 T2 提交完后,最新的余额数据才能被事务 T1 看见,因此额 ACCOUNT2、ACCOUNT3 都是 50;

在「可重复读」隔离级别下,事务 T1只能看见启动事务时的数据,所以余额 ACCOUNT1、余额 ACCOUNT2 的值都是 100,当事务 A 提交事务后,就能看见最新的余额数据了,所以余额 ACCOUNT3 的值是50;

在「串行化」隔离级别下,事务 T2 在执行将余额 100 万修改为 200 万时,由于此前事务T1执行了读操作,这样就发生了读写冲突,于是就会被锁住,直到事务 T1提交后,事务 T2才可以继续执行,所以从 T1的角度看,余额 ACCOUNT1、 ACCOUNT2 的值是 100 ,余额 V3 的值是 50。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值