编程式事务--使用PlatformTransactionManager接口实现事务

软件152 彭梦月

在spring里事务管理有两种实现方式,一个是编程式事务,一个是声明式事务。先从编程式事务开始讲起。

1.java工程的目录结构:

2.首先是applicationContext.xml配置文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:context="http://www.springframework.org/schema/context"  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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<!-- 扫描该路径下的spring组件 -->        <context:component-scan base-package="cn.com.sharpxiajun" />

<!-- 读取资源文件 -->        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">            <property name="locations">                <list>                    <value>classpath:conf/constants.properties</value>                </list>            </property>        </bean>

<!-- 配置数据源 -->         <!--  <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">             <property name="driverClass" value="${db.driverClass}"/>             <property name="jdbcUrl" value="${db.jdbcUrl}"/>             <property name="user" value="${db.user}"/>             <property name="password" value="${db.password}"/>         </bean>-->

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">             <property name="driverClassName" value="${db.driverClass}"/>             <property name="url" value="${db.jdbcUrl}"/>             <property name="username" value="${db.user}"/>             <property name="password" value="${db.password}"/>         </bean>

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">            <property name="configLocation">                <value>classpath:conf/SqlMapConfig.xml</value>            </property>            <property name="dataSource" ref="myDataSource"/>        </bean>

<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">            <property name="sqlMapClient">                <ref local="sqlMapClient"/>            </property>        </bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">            <property name="dataSource">                <ref local="myDataSource"/>            </property>        </bean>

<!-- 将我自己定义的拦截器生成bean -->        <bean id="methodServiceAdvisor" class="cn.com.sharpxiajun.common.aop.MethodServiceAdvisor"/>

<aop:config>            <!--配置规则,满足以下规则的将拦截,第一个*表示所有返回类型,第二个表示service包下的所有class,第三个表示所有方法-->            <aop:pointcut id="baseServiceMethods" expression="execution(* cn.com.sharpxiajun.service.*.*(..))"/>            <!-- 符合上面规则的拦截器都会调用到methodServiceAdvisor -->            <aop:advisor advice-ref="methodServiceAdvisor" pointcut-ref="baseServiceMethods"/>        </aop:config>

</beans>配置文件里添加了<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">。。。事务管理的spring bean。3.在cn.com.sharpxiajun.transactionstudy包下建接口SpringTransaction,代码如下:

4.在包cn.com.sharpxiajun.transactionstudy.impl下实现SpringTransaction接口,代码如下:

package cn.com.sharpxiajun.transactionstudy.impl;

import java.sql.Connection;import java.sql.SQLException;import java.sql.Statement;

import org.apache.commons.dbcp.BasicDataSource;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Scope;import org.springframework.jdbc.datasource.DataSourceUtils;import org.springframework.stereotype.Service;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.DefaultTransactionDefinition;

import cn.com.sharpxiajun.transactionstudy.SpringTransaction;

@SuppressWarnings("unchecked")@Scope("prototype")@Service("springTransaction")public class SpringTransactionImpl implements SpringTransaction {

private final static Log log = LogFactory.getLog(SpringTransactionImpl.class);

@Autowired    @Qualifier("myDataSource")    private BasicDataSource myDataSource = null;

@Autowired    @Qualifier("transactionManager")    private PlatformTransactionManager transactionManager = null;

public void transactionInsert()    {        DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();        dtd.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);        TransactionStatus ts = transactionManager.getTransaction(dtd);        Connection conn = DataSourceUtils.getConnection(myDataSource);

try {            Statement stmt = conn.createStatement();            stmt.execute("insert into users values(‘sharpxiajun‘,‘sharpxiajun‘,true)");            stmt.execute("insert into users values(‘java‘,‘java‘,true)");            transactionManager.commit(ts);            log.info("事务成功完成!");        } catch (SQLException e) {            transactionManager.rollback(ts);            log.info("事务执行失败");            System.out.println("原因:" + e.getMessage());        }    }

}

5.在cn.com.sharpxiajun.junittest.transactionstudy包下建立测试类SpringTransactionImplTest,代码如下:
package cn.com.sharpxiajun.junittest.transactionstudy;

import org.junit.After;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.test.context.transaction.TransactionConfiguration;

import cn.com.sharpxiajun.transactionstudy.SpringTransaction;

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath:conf/applicationContext.xml" })@TransactionConfiguration(defaultRollback = false)public class SpringTransactionImplTest extends        AbstractTransactionalJUnit4SpringContextTests {

@Autowired    private SpringTransaction springTransaction = null;

public SpringTransactionImplTest()    {        System.out.println("初始化测试类....");    }

@Before    public void setUp() throws Exception    {        System.out.println("测试开始....");    }

@After    public void tearDown() throws Exception    {        System.out.println("测试结束!!");    }

@Test    public void testTransactionInsert()    {        springTransaction.transactionInsert();    }

}

运行测试类,结果如下:
log4j: Parsing for [root] with value=[INFO,CONSOLE,STDOUT].log4j: Level token is [INFO].log4j: Category root set to INFOlog4j: Parsing appender named "CONSOLE".log4j: Parsing layout options for "CONSOLE".log4j: Setting property [conversionPattern] to [%d{yyyy-MM-dd HH:mm:ss}  %c{1} - %m%n].log4j: End of parsing for "CONSOLE".log4j: Parsed "CONSOLE" options.log4j: Parsing appender named "STDOUT".log4j:ERROR Could not find value for key log4j.appender.STDOUTlog4j: Parsing for [com.ibatis.common.jdbc.SimpleDataSource] with value=[debug].log4j: Level token is [debug].log4j: Category com.ibatis.common.jdbc.SimpleDataSource set to DEBUGlog4j: Handling log4j.additivity.com.ibatis.common.jdbc.SimpleDataSource=[null]log4j: Parsing for [java.sql.Connection] with value=[DEBUG].log4j: Level token is [DEBUG].log4j: Category java.sql.Connection set to DEBUGlog4j: Handling log4j.additivity.java.sql.Connection=[null]log4j: Parsing for [com.ibatis] with value=[debug].log4j: Level token is [debug].log4j: Category com.ibatis set to DEBUGlog4j: Handling log4j.additivity.com.ibatis=[null]log4j: Parsing for [java.sql.Statement] with value=[DEBUG].log4j: Level token is [DEBUG].log4j: Category java.sql.Statement set to DEBUGlog4j: Handling log4j.additivity.java.sql.Statement=[null]log4j: Parsing for [com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate] with value=[debug].log4j: Level token is [debug].log4j: Category com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate set to DEBUGlog4j: Handling log4j.additivity.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=[null]log4j: Parsing for [com.ibatis.common.jdbc.ScriptRunner] with value=[debug].log4j: Level token is [debug].log4j: Category com.ibatis.common.jdbc.ScriptRunner set to DEBUGlog4j: Handling log4j.additivity.com.ibatis.common.jdbc.ScriptRunner=[null]log4j: Parsing for [java.sql.PreparedStatement] with value=[DEBUG].log4j: Level token is [DEBUG].log4j: Category java.sql.PreparedStatement set to DEBUGlog4j: Handling log4j.additivity.java.sql.PreparedStatement=[null]log4j: Finished configuring.log4j:ERROR Could not instantiate appender named "STDOUT".初始化测试类....2011-10-19 22:35:11  XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [conf/applicationContext.xml]2011-10-19 22:35:11  GenericApplicationContext - Refreshing [email protected]c3f5: startup date [Wed Oct 19 22:35:11 CST 2011]; root of context hierarchy2011-10-19 22:35:11  PropertyPlaceholderConfigurer - Loading properties file from class path resource [conf/constants.properties]2011-10-19 22:35:11  DefaultListableBeanFactory - Pre-instantiating singletons in org.s[email protected]19ba640: defining beans [usersDao,springTransaction,userService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,myDataSource,sqlMapClient,sqlMapClientTemplate,transactionManager,methodServiceAdvisor,org.springframework.aop.config.internalAutoProxyCreator,baseServiceMethods,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0]; root of factory hierarchy2011-10-19 22:35:13  TransactionalTestExecutionListener - Began transaction (1): transaction manager [o[email protected]171194d]; rollback [false]测试开始....2011-10-19 22:35:13  SpringTransactionImpl - 事务成功完成!测试结束!!2011-10-19 22:35:13  TransactionalTestExecutionListener - Committed transaction after test execution for test context [[[email protected] testClass = SpringTransactionImplTest, locations = array<String>[‘classpath:conf/applicationContext.xml‘], testInstance = cn.com.s[email protected]1702c48, testMethod = [email protected], testException = [null]]]2011-10-19 22:35:13  GenericApplicationContext - Closing [email protected]c3f5: startup date [Wed Oct 19 22:35:11 CST 2011]; root of context hierarchy2011-10-19 22:35:13  DefaultListableBeanFactory - Destroying singletons in org.s[email protected]19ba640: defining beans [usersDao,springTransaction,userService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,myDataSource,sqlMapClient,sqlMapClientTemplate,transactionManager,methodServiceAdvisor,org.springframework.aop.config.internalAutoProxyCreator,baseServiceMethods,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0]; root of factory hierarchy数据库结果如下:

操作成功了!!!
时间: 2024-10-11 05:11:28

编程式事务--使用PlatformTransactionManager接口实现事务的相关文章

Spring学习8-Spring事务管理(编程式事务管理)

一.Spring事务的相关知识   1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一起失败.    1)jdbc事务:每个Connection都带有一个事务,只是默认被设置为自动提交.一个连接可以有多个事务.对于JDBC,只有在同一个连接内,才有讨论是否提交的前提. 2)Hibernate事务:本质上也是使用JDBC来处理事务.但是不是直接操作,而是使用Session来操作事务.S

全面分析 Spring 的编程式事务管理及声明式事务管理

转自:http://www.open-open.com/lib/view/open1414310646012.html 关于本教程 本教程将深切讲授 Spring 庞杂而丁壮夜的事务治理功用,包括编程式事务和声明式事务.经由进程对本教程的进修,您将可以理解 Spring 事务治理的实质,并无邪运用之. 先决前提 本教程假定您已掌控了 Java 根蒂根抵常识,并对 Spring 有一定意见.您还需求具有根抵的事务治理的常识,好比:事务的界说,隔离级其他概念,等等.本文将直接行使这些概念而不做具体正

Spring笔记(四): spring的编程式事务与声明式事务

一.Spring 事务属性分析 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作过程中机器突然出故障的情况,此时,事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过取款机一样,以保证用户和银行的利益都不受损失. 在 Spring 中,事务是通过 TransactionDefinition 接口来定义的.该接口包含与事务属性有关的方法.在

全面分析 Spring 的编程式事务管理及声明式事务管理--转

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

spring事务管理——编程式事务、声明式事务

本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带有 512MB 内存(

Java学习-编程式的事务管理

编程式事务提供了TransactionTemplate 模板类,该类可以大大减少事务操作的代码.因此TransactionTemplate 采用Callback 避免让开发者重复书写其打开事务.提交事务及回滚事务等代码,同时TransactionTemplate 无须书写大量的try..catch 块. HibernateTemplate 必须提供PlatformTransactionManager 实例.该实例既可以在代码中手动设置,也可以使用Spring 的依赖注入.总之,只要获取了Plat

Spring事务管理的实现方式:编程式事务与声明式事务

本文转载于本人另一博客[http://blog.csdn.net/liaohaojian/article/details/70139151] 1.上篇文章讲解了Spring事务的传播级别与隔离级别,以及分布式事务的简单配置,点击回看上篇文章 2.编程式事务:编码方式实现事务管理(代码演示为JDBC事务管理) Spring实现编程式事务,依赖于2大类,分别是上篇文章提到的PlatformTransactionManager,与模版类TransactionTemplate(推荐使用).下面分别详细介

分析 Spring 的编程式事务管理及声明式事务管理(转)

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

Spring的编程式事务和声明式事务

事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务管理的两种方式 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务使用TransactionTemplate或者直接使用底层的PlatformTransactionManager.对于编程式事务管理,spring推荐使用TransactionTemplate. 声明式事务是建立在AOP之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法