编程式事务--使用PlatformTransactionManager接口实现事务
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编程式事务--使用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 INFO
log4j: 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.STDOUT
log4j: Parsing for [com.ibatis.common.jdbc.SimpleDataSource] with value=[debug].
log4j: Level token is [debug].
log4j: Category com.ibatis.common.jdbc.SimpleDataSource set to DEBUG
log4j: 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 DEBUG
log4j: 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 DEBUG
log4j: 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 DEBUG
log4j: 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 DEBUG
log4j: 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 DEBUG
log4j: 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 DEBUG
log4j: 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 hierarchy
2011-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 hierarchy
2011-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 hierarchy
2011-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
数据库结果如下:
操作成功了!!!
以上是关于编程式事务--使用PlatformTransactionManager接口实现事务的主要内容,如果未能解决你的问题,请参考以下文章