事务管理
什么是事务
事务是现代数据库的核心概念之一,它表示数据库一系列操作的集合。这些操作必须在一个事务当中,要么全部执行成功,要么全部不执行。
acid原则
原子性(atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(consistency)
一个事务执行之前和执行之后都必须处于一致性状态。例如转账,假设用户a和用户b两者的钱加起来一共是5000,那么不管a和b之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
隔离性(isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性(durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
java事务类型
jdbc事务
jdbc事务也称之为本地事务,主要是利用connection对象控制,可以将多个sql语句操作放在一个事务中执行。connection接口提供了两种事务管理的方式:自动提交和手动提交。但是jdbc事务的一个缺点就是事务范围局限于一个数据库连接中,并不能夸多个数据库。
jta事务
jta(java transaction api)是java中的事务标准pai,它与实现和协议无关,应用程序和应用服务器之间可以使用jta来操作事务。jta事务允许应用程序同时操作多个不同的数据库,这些数据库可以分布在不同的网络中,这就是所谓的分布式事务处理。而大部分数据库的jdbc驱动都会支持这种分布式事务处理(通常都会实现xadatasource与xaconnection)。
容器事务(cmt)
容器事务主要由j2ee应用服务器提供,通常指的是ejb容器,这些容器事务大多基于jta事务来实现。相对于编码来实现jta事务管理,我们可以通过容器提供的事务管理机制来完成相同的功能。这样我们不必以硬编码的方式来控制事务,完全由容器托管,我们只需简单的指定哪些方法需要加入事务,一旦指定,容器将负责事务的管理。
spring事务管理
编程式事务
所谓编程式指的是在程序中以编码的方式使用transactiontemplate或者直接使用底层的platformtransactionmanager。对于编程式事务管理,spring推荐使用transactiontemplate。
声明式事务
声明式事务是建立在aop之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,只需要在配置文件中做相应的配置或者使用注解进行事务声明即可。
事务传播性
事务的传播性一般在事务嵌套时候使用,比如在事务a里面调用了另外一个使用事务的方法,那么这俩个事务是各自作为独立的事务执行提交,还是内层的事务合并到外层的事务一块提交,这就是事务传播性要确定的问题。
required
业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么这个时候就会加入到该事务中,如果当前没有事务环境的话,就会为自己创建一个新的事务。
(如果存在一个事务,则支持当前事务。如果没有事务则开启)
supports
如果业务方法a在某个事务范围内被调用,则方法成为事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。即当标注了事务传播属性——supports的业务方法在另一个bean的业务方法中执行时,如果另一个bean的业务方法开启了事务,它就会处在事务中执行,如果另一个bean的业务方法也没开启事务,那么它也在没有事务的环境中进行。
(如果存在一个事务,则支持当前事务。如果没有事务,则非事务的执行)
mandatory
该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器就会抛出异常。一种比较强硬的方式。
(如果存在一个事务,则支持当前事务。如果没有一个活动的事务,则抛出异常)
requires_new
该属性表明不管当前是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行。
( 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起)
not_supported
声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用(在其他业务bean的方法中被调用了,而其他业务bean的方法是开启了事务的),该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。
(总是非事务地执行,并挂起任何存在的事务)
never
指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出异常,只有业务方法没有关联到任何事务,才能正常执行。比较强硬的方式,就是不支持事务。
(总是非事务地执行,如果存在一个活动事务,则抛出异常)
nested
(嵌套事务)如果一个活动的事务存在,则当前方法运行在一个嵌套的事务中。 如果没有活动事务,就创建一个新的事务。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。外部事务回滚会导致内部事务的回滚。如果被调用的内部方法没有捕获异常,跑出异常也会导致外部事务的回滚。
(如果一个活动的事务存在,则运行在一个嵌套的事务中。 如果没有活动事务, 则按transactiondefinition.propagation_required 属性执行 spring事务的隔离级别)
上一篇: pip安装加速
下一篇: Vue+Electron实现简单桌面应用