`

在spring中使用声明型事务

阅读更多
在spring中使用声明型事务
spring使用aop机制管理jdbc的连接和事务。它使用TransactionInterceptor类,Spring事务支持中的核心接口是
org.springframework.transaction.PlatformTransactionManager。为了实际执行事务,Spring所有的事务划分功能都通过传递适当的TransactionDefinition实例,委托给 PlatformTransactionManager。
尽管PlatformTransactionManager接口可以直接使用,应用程序通常配置具体的事务管理器并使用声明性事务来划分事务。
Spring具有多种PlatformTransactionManager实现,它们分为两类:
局部事务策略即针对单个资源执行事务(主要是针对单个的数据库)。实现有 org.springframework.jdbc.datasource.DataSourceTransactionManager。它用于jdbc数据源的配置,调用TransactionInterceptor开是一个事务,
从DataSource得到一个connection并确保auto-commit设为disabled。他用JdbcTemplate在一个线程内绑定一个JDBC connection,TransactionInterceptor负责提交事务,
DataSourceTransactionManager 调用Connection.commit()关闭connection,并解除绑定(potentially allowing for one thread connection per data source)。
例如
<bean id="DataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:hua2</value>
</property>
<property name="username">
<value>user</value></property>
<property name="password">
<value>gotpassword</value>
</property>
</bean>
</beans>
<bean id="DataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="DataSource" />
</bean>
<bean id="tatanTransactionScriptsProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<idref bean="tatanTransactionScripts" />
</list>
</property>
<property name="interceptorNames">
<list>
<idref bean="DataSourceTransactionInterceptor" />
</list>
</property>
</bean>
<bean id="DataSourceTransactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"
ref="DataSourceTransactionManager" />
<property name="transactionAttributeSource">
<value>
com.tatan.tatanTransactionScriptsImpl.*=PROPAGATION_REQUIRED
</value>
</property>
</bean>
transactionAttributesSource 属性指定每个方法的transaction attribute,PROPAGATION_REQUIRED说明在一个事务内这个方法被执行。
和EJB一样,默认的情况下,spring只有当unchecked exception被抛出时,才rollback事务,也可以自己加入checked exception。
tatanTransactionScripts被TransactionInterceptor封装,在一个事物内执行类的每一个方法。
更为简单的配置

<bean id="UserManagerTran"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/></property>
<property name="target"><ref bean="UserManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="insert*">
PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>
<prop key="tran*">
PROPAGATION_REQUIRED, ISOLATION_SERIALIZABLE</prop>
<prop key="deposit*">
PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>

(The TransactionProxyFactoryBean is a ProxyFactoryBean where every bean is adviced with a TransactionInterceptor. And the TransactionInterceptor is a piece of advice.
So you can use a seperate TransactionInterceptor and ProxyFactoryBean. But if you are lazy/smart, you can use the TransactionProxyFactoryBean that does the same thing (only less configuration needed))
对于特定的方法或方法命名模式,代理的具体事务行为由事务属性驱动,如下面的例子所示:
<prop key="insert*">
ROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED
</prop>
key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)。
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。
在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释。

全局事务管理即执行有可能跨越多个资源的全局事务。主要对应的Spring类是org.springframework.transaction.jta.JtaTransactionManager,它委托给遵循JTA规范的J2EE服务器,也有例外。
spring支持JTA,只需要一个标准的JtaTransactionManager定义,数据库必须支持XA protocol,或者J2EE服务器提供支持XA规范的DataSource。
默认的Spring JtaTransactionManager设置将从标准的JNDI位置获取JTA的 javax.transaction.UserTransaction对象,该JNDI位置由J2EE指定:java: comp/UserTransaction。对于大多数标准J2EE环境下的用例来说,它工作良好。
但是,默认的 JtaTransactionManager不能执行事务挂起操作(即它不支持PROPAGATION_REQUIRES_NEW和 PROPAGATION_NOT_SUPPORTED)。原因是标准的JTA UserTransaction接口不支持挂起或恢复事务的操作;它只支持开始和完成新事务的操作。
为执行事务挂起操作,还需要提供javax.transaction.TransactionManager实例,按照JTA的规定,它提供标准的挂起和恢复方法。遗憾的是,J2EE没有为JTA TransactionManager定义标准的JNDI位置!
因此,必须使用特定于供应商的(vendor-specific)查寻机制。J2EE没有考虑把JTA TransactionManager接口作为它的公开API的一部分。JTA规范规定的TransactionManager接口原本是打算用于容器集成的。
但是为JTA TransactionManager定义标准的JNDI位置还是有重大意义的,尤其是对于轻量级容器(如Spring);然后,便可以以同样的方式来定位任意的J2EE服务器的JTA TransactionManager。
结合jboss JTA的Spring事务划分
oracle-ds.xml
<?xml version="1.0" encoding="UTF-8"?>

<datasources>
<xa-datasource>
<jndi-name>XASpringDS</jndi-name>
<track-connection-by-tx/>
<isSameRM-override-value>false</isSameRM-override-value>
<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
<xa-datasource-property name="URL">jdbc:oracle:oci8:@orcl</xa-datasource-property>
<xa-datasource-property name="User">SCOTT</xa-datasource-property>
<xa-datasource-property name="Password">tiger</xa-datasource-property>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<no-tx-separate-pools/>
</xa-datasource>
<mbean
code="org.jboss.resource.adapter.jdbc.xa.oracle.OracleXAExceptionFormatter"
name="jboss.jca:service=OracleXAExceptionFormatter">
<depends optional-attribute-name="TransactionManagerService">
jboss:service=TransactionManager</depends>
</mbean>
</datasources>
spring配置
<!-- Data source bean -->

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:/XASpringDS</value></property>
</bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

Spring有效地将DAO实现从实际的运行时环境中分离出来,允许在J2EE容器之外轻松地测试或重用用。
Spring提供了多种事务策略,比如JtaTransactionManager和JDBC DataSourceTransactionManager,
前者委托给J2EE服务器的事务协调程序,后者则针对单个JDBC DataSource(即单个的目标数据库)执行事务。
通过对后端配置进行简单的更改,就能够轻松地调整事务策略适应另一个环境。
分享到:
评论

相关推荐

    Spring中的四种声明式事务的配置

    在Spring框架中,声明式事务管理是通过AOP(面向切面编程)实现的,它允许开发者无需在业务代码中显式处理事务,而是通过配置来控制事务的边界。Spring提供了四种不同的方式来配置声明式事务,这使得事务管理更加...

    Hibernate编程式事务与Spring Aop的声明式事务(spring与hibernate集成)

    本篇文章将重点讨论如何在Spring框架中集成Hibernate,并探讨编程式事务管理和Spring AOP的声明式事务。 首先,让我们理解Spring与Hibernate的集成。为了整合这两个库,你需要在Spring配置文件中定义Hibernate的...

    4.Spring中的JdbcTemplate,Spring中的的事务,

    #### 在DAO中使用JdbcTemplate 在DAO层使用JdbcTemplate可以有两种方式: 1. **直接在DAO类中定义JdbcTemplate**: ```java public class AccountDao { private JdbcTemplate jdbcTemplate; public void ...

    Spring多数据源分布式事务管理

    在Spring中使用Atomikos,首先需要添加相应的依赖库,并在Spring配置文件中声明Atomikos事务管理器。然后,我们需要配置Atomikos的事务属性,如事务超时时间、回滚规则等。最后,通过@TransactionManagement注解开启...

    struts2.3+spring3.2+mybatis3.1整合注释行事务处理(含jar包)

    在这个整合项目中,使用了注释型的事务管理,这意味着事务的开启、提交和回滚都是通过在方法上添加特定的Spring注解(如@Transactional)来实现的。这种方式的优点在于代码更易读,无需在XML配置文件中进行繁琐的...

    spring hibernate mysql 事务实例

    在IT行业中,数据库事务是确保数据一致性的重要机制,特别是在分布式系统和多层架构中,如Spring、Hibernate和MySQL的组合。本实例将深入探讨如何在这样的环境中实现事务管理。 Spring框架以其强大的依赖注入和AOP...

    day4-Spring JdbcTemplate & 声明式事务.md

    - **使用XML配置**:在Spring配置文件中定义事务管理器,并配置事务规则。 ```xml &lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt; *" ...

    Spring Boot数据库事务控制.zip

    可以指定事务的传播行为(如PROPAGATION_REQUIRED,表示当前方法必须在一个事务中运行,如果没有则新建一个)、隔离级别(如ISOLATION_DEFAULT,表示使用数据库默认的隔离级别)以及超时时间。 3. **事务回滚规则**...

    Spring事务配置的五种方式

    通常只在无法使用声明式事务管理的情况下使用。 5. **基于 AspectJ 的事务管理(AspectJ-based Transaction Management)** 这种方式结合了 AOP 和注解,事务管理完全基于 AspectJ,无需创建代理。事务规则通过 ...

    spring mybatis atomikos 多库分布式事务demo

    如果在多库环境下,Atomikos会确保所有操作在一个事务中执行,保证数据一致性。 在“DT”这个压缩包文件中,应该包含了完成上述配置和实现的代码示例,包括pom.xml文件、配置文件以及相关的Java代码。通过分析这些...

    java+spring+mybatis+mysql+RuoYi-atomikos-实现分布式事务.zip

    在分布式事务中,MySQL需要支持XA协议,以便参与全局事务的协调。 5. **Atomikos**: Atomikos是一个开源的JTA(Java Transaction API)实现,它为分布式事务提供了强大的支持。Atomikos可以管理多个数据库和消息...

    springcloud整合分布式事务框架TX-LCN

    - **编写业务代码**:使用TX-LCN提供的API在业务代码中声明事务边界。 4. **TX-LCN工作原理**: - **开始事务**:TM-Client向TC发送开始事务请求,TC返回一个全局事务ID。 - **执行本地事务**:业务代码执行,TM...

    第二部分spring+hibernate+jta 分布式事务Demo

    通过运行这个Demo,我们可以看到如何在多数据库或者跨系统操作中,通过Spring的声明式事务管理,配合Hibernate和JTA,确保事务的ACID特性(原子性、一致性、隔离性和持久性)得以实现。同时,这个例子也能帮助开发者...

    spring+atomikos+druid分布式事务Demo

    在IT行业中,分布式事务是一个重要的概念,特别是在大型的、高并发的系统中,它确保了数据的一致性...通过理解和运行这个示例,开发者能够掌握如何在Spring环境中使用Atomikos和Druid实现高可用和一致性的分布式系统。

    Spring+Mybatis+MySql+Maven 简单的事务管理案例.rar

    同时,Mybatis的Mapper接口会被Spring代理,以确保其操作在同一个事务中进行。 总结来说,这个案例将展示如何在Spring中配置Mybatis和MySQL,以便在处理数据库操作时使用Spring的声明式事务管理。Maven将用于构建和...

    Spring+MyBatis+Atomikos实现JTA分布式事务

    在代码层面,我们可以使用Spring的`@Transactional`注解来声明方法需要在事务中执行。当这个注解应用到方法上时,Spring会自动启动一个新的JTA事务,如果方法抛出异常,事务会被回滚;反之,如果方法正常结束,事务...

    spring 事务配置方式

    在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。Spring提供了多种事务配置方式,以适应不同的应用场景。以下是对这些配置方式的详细解释: 1. **编程式事务管理(Programmatic ...

    spring声明式事务解析

    此外,还可以使用注解来标记需要在事务中执行的方法,如`@Transactional`,这在Spring MVC或Spring Boot项目中非常常见。这样,当一个带有`@Transactional`注解的方法被调用时,Spring会自动开启事务,如果方法执行...

Global site tag (gtag.js) - Google Analytics