事物处理简介

事物的定义

事务(Transaction)是由一系列对系统中数据进行访问或更新的操作所组成的一个程序执行逻辑单元(Unit)。在计算机术语中,事务通常就是指数据库事务 。在数据库管理系统(DBMS)中,事务是数据库恢复和并发控制的基本单位。它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

例如,银行转帐工作:从源帐号扣款并使目标帐号增款,这两个操作必须要么全部执行,要么都不执行,否则就会出现该笔金额平白消失或出现的情况。所以,应该把他们看成一个事务。

在现代数据库中,事务还可以实现其他一些事情,例如,确保你不能访问别人写了一半的数据;但是基本思想是相同的——事务是用来确保无论发生什么情况,你使用的数据都将处于一个合理的状态:它保证在任何情况下都不会出现在转账后从一个帐户中扣除了资金,而未将其存入另一个帐户的情况。

事务的目的

数据库事务通常包含了一个序列的对数据库的读/写操作。包含有以下两个目的:

  1. 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
  2. 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
    当事务被提交给了DBMS,则DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。

事务的状态

因为事务具有原子性,所以从外部看的话,事务就是密不可分的一个整体,事务的状态也只有三种:Active、Commited 和 Failed,事务要不就在执行中,要不然就是成功或者失败的状态。
Active:事务的初始状态,表示事务正在执行;
Partially Committed:在最后一条语句执行之后;
Failed:发现事务无法正常执行之后;
Aborted:事务被回滚并且数据库恢复到了事务进行之前的状态之后;
Committed:成功执行整个事务。

事务的特性

事务是并发控制的单位,是用户定义的一个操作序列。有四个特性(ACID):

  • 原子性(Atomicity): 事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。

  • 一致性(Consistency): 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

  • 隔离性(Isolation): 一个事务的执行不能被其他事务干扰。

  • 持续性/永久性(Durability): 一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

以上是书面解释,简单来说就是把你的操作统一化,要么所有操作都成功,要么就都不成功,如果执行中有某一项操作失败,其之前所有的操作都回滚到未执行这一系列操作之前的状态。

原子性(Atomicity)

原子性也被称为“全有或全无规则”。它非常好理解,即整个事务要么完整发生,要么根本不发生,不会部分发生。它涉及以下两个操作:

  • 中止:如果事务中止,则看不到对数据库所做的更改。
  • 提交:如果事务提交,则所做的更改可见。

拿转账的例子来说,用户张三给用户李四转账,至少要包含两个操作,用户张三钱数减少,用户李四钱数增加,增加和减少的操作要么全部成功,要么全部失败,是一个原子操作
在这里插入图片描述

一致性(Consistency)

一致性是指,一个事务必须使数据库从一个一致性状态变换到另一个一致性状态(执行成功),或回滚到原始的一致性状态(执行失败)。这意味着必须维护完整性约束,以使在事务之前和之后数据库保持一致性和正确性。

参考上面的示例,假设用户A和用户B两者的钱加起来一共是700,那么不管A和B之间如何转账,转几次账,这一约束都得成立,即事务结束后两个用户的钱相加起来还得是700,这就是事务的一致性。

如果转账过程中,仅完成A扣款或B增款两个操作中的一个,即未保证原子性,那么结果数据如上述完整性约束也就无法得到维护,一致性也就被打破。可以看出,事务的一致性和原子性是密切相关的,原子性的破坏可能导致数据库的不一致。

但数据的一致性问题并不都和原子性有关。比如转账的过程中,用户A扣款了100,而用户B只收款了50,那么该过程可以符合原子性,但是数据的一致性就出现了问题。

一致性既是事务的属性,也是事务的目的。也正如本文开篇所提到的,“事务是用来确保无论发生什么情况,你使用的数据都将处于一个合理的状态“,这里所说的合理/正确,也就是指满足完整性约束。

总的来说,一致性是事务ACID四大特性中最重要的属性,而原子性、隔离性和持久性,都是作为保障一致性的手段。事务作为这些性质的载体,实现了这种由ACID保障C的机制。
在这里插入图片描述

隔离性 (Isolation)

隔离性是指,并发执行的各个事务之间不能互相干扰,即一个事务内部的操作及使用的数据,对并发的其他事务是隔离的。此属性确保并发执行一系列事务的效果等同于以某种顺序串行地执行它们,也就是要达到这么一种效果:
在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。
两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。
还是拿转账来说,在A向B转账的整个过程中,只要事务还没有提交(commit),查询A账户和B账户的时候,两个账户里面的钱的数量都不会有变化。如果在A给B转账的同时,有另外一个事务执行了C给B转账的操作,那么当两个事务都结束的时候,B账户里面的钱必定是A转给B的钱加上C转给B的钱再加上自己原有的钱。

持久性(Permanency)

事务的持久性又称为永久性(Permanency),是指一个事务一旦提交,对数据库中对应数据的状态变更就应该是永久性的。即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够根据事务日志对未持久化的数据重新进行操作,将其恢复到事务成功结束的状态。持久性意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会因为系统故障而被回滚。

spring事物处理两种实现

Spring 支持“编程式事务”管理和“声明式事务”管理两种方式:

  1. 编程式事务: 编程式事务使用 TransactionTemplate 或者直接使用底层的 PlatformTransactionManager 实现事务。 对于编程式事务 Spring 比较推荐使用 TransactionTemplate 来对事务进行管理。

  2. 声明式事务: 声明式事务是建立在 AOP 之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况“提交”或者“回滚”事务。

spring 配置式事务要达到的效果是:

  1. 对指定的类的方法添加事务,

  2. 配置管理,不需要每个数据库造作都像上面一样写那么多代码,

  3. spring的配置式事务可以吧多个操作数据库的方法配置在一个事务中,

spring两大特性

控制反转(IoC)

控制反转,简单点说,就是创建对象的控制权,被反转到了Spring框架上。

通常,我们实例化一个对象时,都是使用类的构造方法来new一个对象,这个过程是由我们自己来控制的,而控制反转就把new对象的工交给了Spring容器。

主要意思为:

IoC的主要实现方式有两种:依赖查找、依赖注入。

依赖注入是一种更可取的方式。

那么依赖查找和依赖注入有什么区别呢?

依赖查找,主要是容器为组件提供一个回调接口和上下文环境。这样一来,组件就必须自己使用容器提供的API来查找资源和协作对象,控制反转仅体现在那些回调方法上,容器调用这些回调方法,从而应用代码获取到资源。

依赖注入,组件不做定位查询,只提供标准的Java方法让容器去决定依赖关系。容器全权负责组件的装配,把符合依赖关系的对象通过Java Bean属性或构造方法传递给需要的对象。

面向切面编程(AOP)

面向切面编程(AOP)就是纵向的编程。比如业务A和业务B现在需要一个相同的操作,传统方法我们可能需要在A、B中都加入相关操作代码,而应用AOP就可以只写一遍代码,A、B共用这段代码。并且,当A、B需要增加新的操作时,可以在不改动原代码的情况下,灵活添加新的业务逻辑实现。

在实际开发中,比如商品查询、促销查询等业务,都需要记录日志、异常处理等操作,AOP把所有共用代码都剥离出来,单独放置到某个类中进行集中管理,在具体运行时,由容器进行动态织入这些公共代码。

AOP主要一般应用于签名验签、参数校验、日志记录、事务控制、权限控制、性能统计、异常处理等。

事务的传播特性

就是多个事务方法相互调用时,事务如何在这些方法间传播。
一、除了事务的传播行为外,事务的其它特性 Spring 是借助底层资源的功能来完成的,Spring 无非只充当个代理的角色。但是事务的传播行为却是

Spring 凭借自身的框架提供的功能,是 Spring 提供给开发者最珍贵的礼物,讹传的说法玷污了 Spring 事务框架最美丽的光环。
二、Spring 事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务。结果造成开发人员在设计事务方法时束手束脚,生怕一不小心就踩到地雷。

三、在我们用SSH开发项目的时候,我们一般都是将事务设置在Service层那么当我们调用Service层的一个方法的时候它能够保证我们的这个方法中执行的所有的对数据库的更新操作保持在一个事务中,在事务层里面调用的这些方法要么全部成功,要么全部失败。那么事务的传播特性也是从这里说起的。

四、如果你在你的Service层的这个方法中,除了调用了Dao层的方法之外,还调用了本类的其他的Service方法,那么在调用其他的Service方法的时候,这个事务是怎么规定的呢,我必须保证我在我方法里掉用的这个方法与我本身的方法处在同一个事务中,否则如果保证事物的一致性。

五、默认情况下当发生RuntimeException的情况下,事务才会回滚,所以要注意一下如果你在程序发生错误的情况下,有自己的异常处理机制定义自己的Exception,必须从RuntimeException类继承这样事务才会回滚!

六、当我们项目中仅仅使用hibernate,而没有集成进spring的时候,我们在一个service层中调用其他的业务逻辑方法,为了保证事物必须也要把当前的hibernatesession传递到下一个方法中,或者采用ThreadLocal的方法,将session传递给下一个方法,其实都是一个目的。

怎么理解spring事务的传播特性

Spring中通过Propagation来设置事务的传播属性的,在这个属性中提供了我们其中关于事务传播的特性:

  1. PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

  2. PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

  3. PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。

  4. PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

  6. PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

  7. PROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的甘蔗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值