数据库事务

数据库事务干什么的?

事务事务主要是为了保证复杂数据库操作一致性,尤其是在多并发访问数据时

MYSQL事务主要是用来处理操作量大复杂度高的数据。

什么是数据库事务?

从根本上理解MYSQL事务,是指作为单个逻辑工作单元执行的一系列操作,简单理解就是:要么成功完全的执行,要么失败全部回滚(撤销失败事务对当前数据库造成的影响,我们把这个撤销的过程称之为回滚)。

经典例子:

用户A想往用户B账户转100块;

正常逻辑就是:首先在A的账户里扣除100块钱,然后B账户里面增加100块钱,则表示操作完成。

这是正常情况,接下来看另外的情况:

   

A账户里面扣除100块钱,这条操作语句执行完毕,正要执行给B账户添加100块钱,这个时候系统出现了问题,宕机了程序没有按照流程往下走。这个时候A账户里面少了100块钱,可是B账户里面没有增加100块钱。遇到这种情况下我们该怎么弄呢?这个时候该用到事务了。

  

上面说过,作为单个逻辑工作单元执行的一系列操作,要么成功完全执行,要么失败全部回滚(撤销失败事务对当前数据库造成的影响,我们把这个撤销的过程称之为回滚)。就是说系统要么全部给我走完,要么执行到一半失败了进行回滚:用户A账户里扣100块钱,准备往用户B账户里加100的时候出现了各种因素导致的问题,好嘛,出现问题就出现问题,我再回滚给A账户里面加回100元不就好了嘛。

>事务有哪些状态?

事务一共分为五个状态:

  1. 活动的(active):事务对应的数据库操作在执行过程中,该事务就会处于活动的状态。        
  2. 部分提交的:( partially committed):当数据库事务中的最后一个操作执行完成,但犹豫操作都在内存中执行,所以造成的影响并没有更新到磁盘时,该事务就处在部分提交的状态
  3. 就是说在内存中执行完毕,没有在磁盘中更新,表示事务部分提交
  4. 提交的(committed):当一个处在部分提交的状态事务将修改过的数据都同步到磁盘之后,该事务就处于提交的状态。内存中执行完毕,磁盘中也更新了,表示提交完毕
  5. 失败的(failed):当事务处在活动或者是部分提交的状态时,可能会遇到某些错误(数据库自身错误,操作系统的错误或者是外界因素导致的)而无法继续执行,或则认为的停止当前的事务的执行,该事务就处在失败状态。
  6. 中止的(aborted):如果事务执行了半截而变成失败的状态撤销失败事务对当前数据库造成的影响,我们把这个撤销的过程称之为回滚,当回滚的操作执行完毕,也就是数据库恢复到之前的状态,该事务就会处于终止状态。

 

 >事务有哪些特征?

事务总共有四大特征:

1,原子性(Atomicity)

原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚到执行之前的状态,就像这个事务从来没有执行过一样。事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

2,一致性(Atomicity)

一致是指事务必须使数据库从一个一致状态变换到另一个一致性的状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

假设账户A和账户B两者的钱加起来一共是200,那么不管A和B之间如何转账,转多少次,事务结束后两账户钱加起来还是200,这就是事务的一致性;

打个比方就是,你买个东西这种情况,是不会影响其他人的; 

3,隔离性(lsolation)

多个事务之是相互隔离的,互不影响。数据库允许多个并发同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致的数据不一致。

比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

4,持久性(Durability)

持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到的故障的情况下也不会丢失提交事务的操作。

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

>什么是脏读,不可重复读,幻读?

脏读:简单来说,就是一个事务读取到了另一个事务未提交的数据。

不可重复读:就是说,比如在A事务中进行多次相同的查询,B事务在A事务多次查询之间修改对应表中的数据,导致A事务多次读取的结果不一致。

幻读:举例来说,就是A事务将表中'性别'列的值都更改为1,B事务在A事务修改之后又添加了一条记录,而'性别'的值为0,回过来A再查询所以的记录时会发现有一条记录的'性别'为0,这种情况就是所谓的幻读

 

>隔离性的四个级别:

Read uncommitted (读未提交):最低级别,以上问题均无法解决。

Read committed (读已提交):读已提交,可避免脏读情况发生。

Repeatable Read(可重复读):确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。

Serializable (串行化):最严格的事务隔离级别,要求所有事务被串行执行,不能并发执行,可避免脏读、不可重复读、幻读情况的发生。

 以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然隔离级别越高,越能保证数据的完整性和统一性,但是执行效率就越低,对并发性能的影响也越大。

 事务使用步骤如下:

步骤一,在spring.xml配置文件中引入<tx:>命名空间<beansxmlns="...."..>

步骤二, 使用下面注解的bean自动配置为声明式事务支持

@Transactional

步骤三,在接口或者声接口的实现类的具体方法,可以覆盖类声明处的设置 @Transactional   //类级的注解、适用于类中所有的public的方法明处,写一个@Transaction.要写在接口上写,接口的实现类就会继承下来

@Transactional 的使用注意事项总结
1)@Transactional 注解只有作用到 public 方法上事务才生效,不推荐在接口上使用;
2)避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效;
3)正确的设置 @Transactional 的 rollbackFor 和 propagation 属性,否则事务可能会回滚失败;
4)被 @Transactional 注解的方法所在的类必须被 Spring 管理,否则不生效;
5)底层使用的数据库必须支持事务机制,否则不生效。

事务的七种传播行为

什么是事务的传播行为:事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。

  • PROPAGATION_REQUIRED 表示当前方法必须在一个具有事务的 上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。( 如果被调用端发生异常,那

    么调用端和被调用端事务都将回滚)

  • PROPAGATION_SUPPORTS 表示当前方法不必需要具有一个事务 上下文,但是如果有一个事务的话,它也可以在这个事务中运行
  • PROPAGATION_MANDATORY 表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
  • PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
  • PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。
  • PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常
  • PROPAGATION_NESTED表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中 ,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation. required的一样
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值