事务

事务的特性

事务就是为了保证一组数据库操作,要么全部成功,要么全部失败。

  1. 原子性:一个事务是不可分割的单位,要么整个事务都会执行,要么整个事务都不执行。
    基于回滚方式实现:事务中的操作执行到一半发现出错了,此时就会自动执行一系列逆向的操作,把原来的情况还原回去。
    举例:转账问题,A给B转账,先给A的账户扣钱,再给B的账户加钱,A扣钱之后,系统出现bug,B没有收到钱,通过回滚方式那么A扣的钱就会补回去。
  2. 一致性:事务执行前后,数据处于合法的状态。
    举例:转账问题,A给B转5000元,那么A的账户就减少5000,B的账户就增加5000,如果A中的账户不足,那么就会终止操作,并且进行回滚,账户余额不可能为负。
  3. 持久性:事务一旦执行完毕,这样的修改就是一直生效的。
    举例:转账问题,A给B转5000元,那么A的账户就会永久的减少5000,B的账户就会永久的增加5000,此操作是永久生效的。
  4. 隔离性:和并发密切相关。多个事务并发执行的时候,事务之间内部的操作是相互隔离的(不会相互影响)。

事务希望最终处理完毕之后,数据能正确,又希望在执行很多事务的时候,尽可能让事务并发执行,提高效率。
要提高效率就需要提高并发性,那么隔离性就会降低,数据就容易出错。
要使数据不出错,就要提升隔离性,降低并发性,就会降低效率。

事务中常见的并发问题
  1. 脏读:如果事务1对数据进行修改,并且在提交之前,事务2读取了这个临时的数据,而事务1又撤销了修改,那么事务2 读到的就是不正确的数据,这样的动作就是“脏读”。
    举例:我正在写代码,写了一个Student类,给这个类中加了一个String name成员,同学A过来看到了String name成员并且记住了,A走后,我删掉了name成员,然后我提交了代码,此时A读到的这个数据,就是“脏数据”,这样的动作就是脏读。
    原因:写操作和读操作并发进行,没有进行任何的隔离性的控制,于是就会出现脏读。并发性最高,隔离性最差,数据最容易出现问题。
    解决方案:给写操作进行加锁。事务在修改数据时,不能进行读取,修改完毕并提交之后才能进行读取。

  2. 不可重复读: 在同一个事务中,两次执行读操作,读到的数据结果不一样。
    举例:我将代码提交了之后,其他人进行查看,此时我继续修改Student,把name成员加上了再次提交,此时,其他人再刷新网页,就会发现多了name成员。
    原因:当前虽然进行了写加锁,但是在读操作中,仍然可以继续修改,继续提交,那么数据就会一直在变。
    解决方案:给读操作加锁。此时并发程度降低,隔离性提高,效率降低,数据正确性提高。

  3. 幻读:同一个事务中,两次进行查询得到的结果集不一样。
    举例:此时我已经提交了Student,其他人进行查看,而我又创建了一个Teacher类,修改了代码并提交,导致读取的时候就会发现多了一个类。
    原因:虽然进行了读加锁和写加锁,但是仍然可以插入和删除新的记录。
    解决方案:串行化执行,此时并发性最低,数据的隔离性最高,程序的效率最低,数据正确性最高。

隔离级别

在数据不出错的前提下,尽量提高并发程度,需要根据具体的场景来选择隔离级别:

  1. read uncommitted:允许读取未提交的数据,并发程度最高,隔离性最低,肯能产生脏读。
  2. read committed:只能读取提交后的数据,相当于写加锁,并发程度降低,隔离性提高,不会产生脏读,但是可能存在不可重复读。
  3. repeatable read:相当于给读和写都加锁,并发程度又降低了,隔离性又提高了,不会脏读,也不会不可重复读,但是可能存在幻读。
  4. serializable:严格串行化执行,并发程度最低,隔离性最高。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值