事务的编程模型

在上一篇文章里面写了关于事务的一些特性,这里在谈谈事务的编程模型。什么叫做事务的编程模型,这个问题比较难以回答,其实简单的一句话,就是我们如何去使用和控制事务。在java平台里面,有三种事务编程模型:本地事务模型,编程式事务模型,声明式事务模型(当然我不是太认同这种说法,并不是太准确,不过大体也就这么回事情)

  • 本地事务模型

本地事务模型:不用事务的编程框架来管理事务,直接使用资源管理器来控制事务。典型的就是java.sql.Connection 中的 setAutoCommit、commit、rollback方法,见下面一段代码,直接使用资源管理器进行事务控制

        Connection conn = getConnection();
        conn.setAutoCommit(false);
        // do something
        boolean success = doSomething();
        if (success) {
            conn.commit();
        } else {
            conn.rollback();
        }
    

  • 编程式事务模型

编程式事务模型:就是使用java提供的事务api JTA(Java Transaction API)

和事务服务提供者(一般是指j2ee容器) 进行事务控制,JTA里面提供了 java.transaction.UserTransaction ,里面定义了下面几个方法

begin:开启一个事务

commit:提交当前事务

rollback:回滚当前事务

setRollbackOnly:把当前事务标记为回滚

setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务

getStatus;

不过JTA只是提供了一个接口,并没有提供具体的实现,而是由j2ee服务器提供商 根据JTS规范提供的。下面一段代码演示了如何使用事务JPA

        InitialContext ctx = new InitialContext();
        UserTransaction ut = (UserTransaction)
    ctx.lookup("javax.transaction.UserTransaction");
        
        ut.begin();
        //do something
        boolean isSuccess = doSomething() ;
        
        if(isSuccess){
            ut.commit();
        }else{
            ut.rollback();
        }

JPA规范里面定义了事务相关的几个角色:事务上下文,资源管理器,通信管理器,应用程序,事务管理器,事务服务提供者。其中资源管理器主要就是我们常见的数据库连接和JMS连接,事务上下文这里可以理解为事务的状态和属性信息,应用程序就是使用事务服务的程序,事务服务提供者就是实现了jta规范的j2ee容器。事务管理器就是应用程序和事务服务提供者的api接口。通信管理器主要是用在分布式事务里面。

这个是java里面JPA的规范,但是也有一些编程框架提供了自己的编程事务模型,例如java里最常用的就是spring的事务管理器,下面是spring提供的编程接口:org.springframework.transaction.PlatformTransactionManager,这里面就只有三个方法:

getTransaction:根据属性信息决定是否开启事务(具体可以看上一篇文章里面的事务特性小结里面的事务传播属性)

commit;提交当前事务

rollback;回滚当前事务

我们发现其实和JPA提供的编程模型很像,就是开启一个事务,提交还是回滚事务。spring提供的事务编程框架也比较简单

ApplicationContext context = getApplicationContext();
        TransactionTemplate transactionTemplate = (TransactionTemplate)context.getBean("TransactionTemplate");
        
        transactionTemplate.execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus status) {
                boolean isSuccess = doSomething() ;

                if(isSuccess){
                    
                }else{
                    status.setRollbackOnly();
                }
                return isSuccess;
            }    
        });

  • 声明式编程

声明式编程:这种编程模型不采用硬编码的方式,而是采用在xml里面进行配置的方式或者使用anotation的方式进行。例如srping里面可以通过aop进行实现

<bean id="accountService"
class="org.springframework.transaction.interceptor. TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/> 
<property name="target" ref="accountServiceTarget"/>
<property name="transactionAttributes">
<props>
   <prop key="*">PROPAGATION_SUPPORTS</prop>   <prop key="update*">PROPAGATION_REQUIRED </prop> </props> </property>

以上三种编程模型,第一种比较简单,也只是适合控制单个资源事务,如果涉及到跨资源(比如两个数据库连接之间)事务控制,就无能为力了,也就是说不能够提供分布式事务的解决方案, 而JPA提供了分布式事务的解决方案,这一块以前了解过,后来忘记了,准备在温习一下,在整理和总结以下。而spring提供的编程事务模型,则是在局部事务和JPA事务的基础上提供了一层封装,统一了两者的编程模型,也就是说spring其实也提供JPA的编程接口,也就是 JtaTransactionManager,只不过具体实现 委托给jta provider而已。所以基本上编程模型这个划分还是比较模糊的,直接使用spring提供的编程模型即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是两个代码片段可用于在Spring XML配置文件中启用注解驱动的事务编程模型: 1. 使用tx命名空间: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 配置数据源和事务管理器 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 配置数据源 --> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 启用注解驱动的事务 --> <tx:annotation-driven /> <!-- 配置需要事务管理的业务类 --> <bean id="myService" class="com.example.MyServiceImpl"> <property name="myDao" ref="myDao" /> </bean> <bean id="myDao" class="com.example.MyDaoImpl"> <property name="dataSource" ref="dataSource" /> </bean> </beans> ``` 2. 使用aop命名空间: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 配置数据源和事务管理器 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 配置数据源 --> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 启用注解驱动的事务 --> <tx:annotation-driven /> <!-- 配置需要事务管理的业务类 --> <bean id="myService" class="com.example.MyServiceImpl"> <property name="myDao" ref="myDao" /> </bean> <bean id="myDao" class="com.example.MyDaoImpl"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置事务切面 --> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* com.example.*Service.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> </beans> ``` 以上两个配置方式都可以启用注解驱动的事务编程模型,其中使用tx命名空间的方式更为简洁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值