Spring 事物配置--XML

事务的传播规则:

在一个事务方法中调用了其他的事务方法,此时事务该如何传递,按照什么规则传递

例如有两个service,A和B

A service类            |    B service类

                       |

private serviceB SB;   |  

public void AAA(){     |  public void BBB(){

TODO               |   TODO

SB.BBB();          |

}                      |  }

Aservice中的业务方法,调用了Bservice中的方法,同时两个业务方法中又有不同的事务操作,

问题来了,那他们的事务该怎么运行传递呢?

    //事务传播规则

    int PROPAGATION_REQUIRED = 0;

    int PROPAGATION_SUPPORTS = 1;

int PROPAGATION_MANDATORY = 2;

int PROPAGATION_REQUIRES_NEW = 3;

int PROPAGATION_NOT_SUPPORTED = 4;

int PROPAGATION_NEVER = 5;

int PROPAGATION_NESTED = 6;

第一种情况:需要尊重/尊从当前事务

 

REQUIRED:必须的意思,必须存在一个事务,则加入到该事务中,否则,新建一个事务,使用比较多的情况。

比如,在AAA()中调用BBB(),AAA()中存在事务,则就使用该事务,不存在,则BBB()新建一个事务。

 

SUPPORTS:支持,如果当前有事务,则使用该事务,如果当前没有事务,则以非事务的方式运行。

比如,在AAA()中调用BBB(),AAA()中存在事务,则就使用该事务,AAA()不存在事务,则不使用事务运行BBB()。

 

MANDATORY:必须存在事务,如果当前存在事务,就是用该事务,否则,就会出现非法事务异常(IIlegalTranactionStatusException)

 

第二种情况:不尊从当前事务

 

REQUIRES_NEW:不管当前是否存在事务,都会开启一个事务,必须是一个新的事务,在开发中使用的比较多,根据业务的情况。

 

NOT_SUPPORTED:一定要以非事务的方式执行,如果当前存在事务,就会把当前的事务挂起。

比如,在AAA()中调用BBB(),AAA()中存在事务,在BBB()中不要事务,则该事务进行挂起,等AAA()调用完BBB(),

又回到AAA()的时候  又拿着之前的事务来用。我们用的不多

 

NEVER:不支持事务,如果当前存在事务,马上抛出异常(IIlegalTranactionStatusException),不能有事务,有事务就报异常

 

情况三:寄生事务(外部事务/内部事务/嵌套事务)

 

NESTED:寄生事务,如果当前存在事务,则在内部事务内执行,

                如果当前不存在事务,则创建一个新的事务。

                寄生事务可以通过数据库的savePoint(保存点)来实现,寄生事务可以回滚回来,

                但是他们的回滚不影响外部事务,但是外部事务的回滚会影响寄生事务。

                在以后的开发过程中用的不多

 

//隔离级别

int ISOLATION_DEFAULT = -1;

int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;

int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;

int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;

int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;

//事务超时时间

int TIMEOUT_DEFAULT = -1;

 

 

 

事务管理:   数据源:数据库

案例:银行转账

Spring的事务增强

XML形式:

事务三步骤:what when where

第一步:what--做什么增强!    事务管理器(配置一个id,取个名字)   引入一个连接池对象(DataSource)

<bean id="trans" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="DataSource"/>

</bean>

 

第二步:when--什么时机做增强,环绕增强(配置一个id,取个名字)--表现的是在什么时机做增强---前提的引入tx的命名空间

 

<tx:advice id="txAdvice" transaction-manager="trans">//transaction-manager有一个默认值:transactionManager,

<tx:attributes>

<tx:method name="Change"/>

</tx:attributes>

</tx:advice>

 

2 when 和 1 what,要进行关联,如果不关联的话,就会出现各干各的,没有关联,那就没有意义了,所以环绕增强要和事务管理器进行关联,环绕增强内包含一个事务管理器.

   (1)transaction-manager有一个默认值:transactionManager,这个属性和值可以不写,不写的话,what中的事务管理器的id要改为transactionManager。

   (2)如果自定义事务管理器的id的话,环绕增强的事务管理的值,一定是事务管理器自定义的名字.dataSource id="trans"-->transaction-manager="trans".

   (3)对事务增强的属性配置(tx:attributes):里面可以存在多个tx:method,表示哪些方法要做事务增强。--业务层。

第三步:where --在什么范围做事务增强, 配置切面(aop)

<aop:config>

<aop:pointcut expression="execution(* Spring_Data.transforMoney.*(..))" id="txpc"/>

<aop:advisor advice-ref="txAdvice" pointcut-ref="txpc"/>

</aop:config>

2 when 和 3 where要进行关联,

(1)配置一个aop:pointcut,首先给aop:pointcut取个名字(txpc),然后在配置一个表达式,表示事务增强的作用域。

(2)配置一个aop:advisor,有两个属性,advice-ref:属性的值为环绕增强的ID值,要进行关联(3 where 和2 when要进行关联)

                              pointcut-ref:属性的值为切点的ID值,这样切点aop:pointcut又和aop:advisor关联起来了。

最终:归结点在于事务增强的作用域和作用域之内的方法

aop:pointcut-->aop:advisor-->tx:advice-->DataSourceTransactionManager:穿成一条线。

 

事务管理器之环绕增强的属性:<tx:method/>的属性值

<tx:attributes>

<tx:method name="Change"/>

</tx:attributes>

 

name                必填       要进行事务管理的方法名称,支持通配符方式:*,匹配方法的模式(Change*):例如Changexxx、Changeaaa。。。。

propagation         非必填     事务的传播规则  

- REQUIRED 默认值

- SUPPORTS

- MANDATORY

- REQUIRES_NEW

- NOT_SUPPORTED

- NEVER

isolation           非必填    隔离级别   建议使用默认值,其他四种是Spring模拟出来的,我们一般不用。我们用DEFAULT不会使用

- DEFAULT  默认值

- READ_UNCOMMITTED 

- READ_COMMITTED

- REPEATABLE_READ

- SERIALIZABLE

timeout             非必填   事务超时时间

    - -1 默认值

read-only           非必填   是否是只读事务        比如在hibnate中设置read-only=“true”可以提高性能,一般只有查询的时候  我们可以设置为true,

可以提高性能

rollback-for        非必填   因为什么做事务回滚    遇到什么异常进行回滚

      当我们在业务方法中抛出了一个runtimeException异常,事务就要回滚,抛给用户看,

      并让用户知道之前的操作统统给取消掉。多个异常的时候可以使用逗号隔开 rollback-for="Exception,Exception"

    - java.lang.RuntimeException 默认值

no-roback-for       非必填   遇到什么异常不回滚  

 

配置方法属性的规则

首先在创建业务方法的时候 要遵循一定的方法命名规范

然后在配置方法的属性的时候使用名称的前缀+*

比如查询操作

<tx:method name="get*" read-only=“true”/>

<tx:method name="list*" read-only=“true”/>

<tx:method name="query*" read-only=“true”/>

//*非查询方法

<tx:method name="*"/>

 

配置事务(****)增强的流程图:

首先明确 三部分 1.事务管理器(what) 2.AOP切面(where) 3.事务增强(when)

1 <bean id="a" TXmanager/>

2 <aop:config>

      <aop:pointcut excution="(* 包.子包.类.*(**))" id="c" >

      <aop:advicer pointcut-ref="c" advice-ref="b">

  </aop:config> 

3 <tx:advice id="b" mage="a"

     <tx:methed=""    

 

 

 

 

 

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring事务失效的情况有以下几种: 1. 代码中未正确使用@Transactional注解或使用错误的Propagation等级导致事务不会被启动或继承; 2. 在方法内部捕获了异常,但没有将其抛出,导致事务无法回滚; 3. 在同一方法内部调用了另一个带有@Transactional注解的方法,但是该注解被忽略了; 4. 在同一类中的两个带有@Transactional注解的方法互相调用,但是没有使用代理对象调用另一个方法,导致事务被忽略; 5. Spring和JPA实现之间的一些特殊情况,例如在同一事务中使用多个数据库连接或跨线程使用EntityManager等。 以上是常见的Spring事务失效的情况,需要注意并避免。 ### 回答2: Spring事务失效的情况有以下几种: 1. 没有配置事务管理器:在Spring中,需要通过配置事务管理器来启用事务处理。如果没有正确配置事务管理器或未进行任何事务配置,那么事务将无法生效。 2. 方法没有被注解为事务:在使用注解来管理事务时,需要在需要添加事务的方法上添加相应的事务注解,比如@Transactional。如果忘记在方法上添加注解或添加错误的注解,事务将无法生效。 3. 异常没有正确处理:事务的生效与异常的处理密切相关。如果在事务方法中发生了未被捕获的异常,并且该异常未被正确处理,事务就会失效。通常,当遇到异常时,应该正确地处理异常,包括回滚事务或进行其他适当的操作。 4. 事务的传播属性设置不正确:在Spring中,可以通过设置事务的传播属性来控制事务的行为。如果在事务方法中设置的传播属性不正确或与预期不符合,事务可能会失效。例如,如果设置了Propagation.REQUIRES_NEW,但实际上需要使用Propagation.REQUIRED,则事务将不会生效。 5. 数据库连接未关闭或未释放:在使用Spring事务时,需要确保数据库连接在事务完成后被正确地关闭或释放。如果没有正确地关闭或释放数据库连接,可能会导致事务失效或遇到其他问题。 总之,要保证Spring事务正常生效,需正确配置事务管理器、使用正确的事务注解、处理异常、设置正确的事务传播属性,并确保数据库连接的正确关闭或释放。 ### 回答3: Spring事务失效可能出现以下情况: 1. 没有正确配置事务管理器:Spring框架依赖于事务管理器来处理事务操作,如果没有正确配置事务管理器,事务将无法起作用。 2. 在没有注解或XML配置的情况下,手动提交或回滚事务:在Spring中,事务可以通过注解或XML配置来自动管理。如果没有进行正确的配置,手动提交或回滚事务可能会导致事务失效。 3. 事务传播属性设置错误:事务传播属性用于确定事务在不同方法调用间如何传播。如果事务传播属性设置错误,可能导致事务失效或不起作用。 4. 异常未正确处理:在事务方法中,如果异常未正确处理或捕获,事务可能会失效。应该使用try-catch块来捕获异常,并在catch块中进行回滚或处理。 5. 方法未被代理:Spring事务通常由动态代理来实现。如果方法没有被代理,事务将无法生效。确保类被正确配置Spring Bean,并从Spring容器中获取实例来处理事务。 6. 事务超过预定的时间或资源限制:如果事务操作超过了数据库或系统设置的时间或资源限制,可能会导致事务失效。应该根据业务需求和系统资源合理设置事务的超时时间和资源限制。 总之,在使用Spring事务时,需要确保正确配置事务管理器、正确设置事务传播属性、正确处理异常、方法被正确代理,并根据实际需求合理设置事务的超时时间和资源限制,以避免事务失效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值