软件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