Spring的事务管理,有两种方式实现,一种是在代码中编写,一种是声明式事务。在代码中编写要更加细粒度,而很多时候我们只需要简单的事务处理,那就可以用声明式事务。
Spring的事务管理器:
事务管理器实现 |
目标 |
org.springframework.jdbc.datasource.DataSourceTransactionManager |
在JDBC DataSource中管理事务 |
org.springframework.orm.hibernate.HIbernateTransactionManager |
管理Hibernate事务 |
org.springframework.orm.jdo.JdoTransactionManager |
管理JDO事务 |
org.springframework.transaction.jta.JtaTransactionManager |
使用一个JTA管理事务,在一个事务跨越多个资源时必须使用 |
org.springframework.orm.ojb.PersistenceBrokerTransactionManager |
管理Apache的OJB事务 |
这些事务管理器的的父类都是PlatformTransactionManager.
下面实例使用DataSourceTransactionManager来管理JDBC事务。
查看Spring的配置信息:(applicationContext.xml)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 5 6 <bean id="propertyConfig" 7 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 8 <property name="location"> 9 <value>connect.properties</value> 10 </property> 11 </bean> 12 13 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 14 <property name="driverClassName"> 15 <value>${db.driver}</value> 16 </property> 17 <property name="url"> 18 <value>${db.url}</value> 19 </property> 20 <property name="username"> 21 <value>${db.username}</value> 22 </property> 23 <property name="password"> 24 <value>${db.password}</value> 25 </property> 26 </bean> 27 28 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 29 <property name="dataSource"> 30 <ref bean="dataSource" /> 31 </property> 32 </bean> 33 34 <!-- JDBC事务管理器 --> 35 <bean id="transactionManager" 36 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 37 <property name="dataSource"> 38 <ref bean="dataSource" /> 39 </property> 40 </bean> 41 42 <!-- 声明事务模板 --> 43 <bean id="transactionTemplate" 44 class="org.springframework.transaction.support.TransactionTemplate"> 45 <property name="transactionManager"> 46 <ref bean="transactionManager" /> 47 </property> 48 </bean> 49 50 <bean id="bankDao" class="com.sunflower.dao.BankDaoImp"> 51 <property name="jdbcTemplate"> 52 <ref bean="jdbcTemplate" /> 53 </property> 54 <property name="transactionTemplate"> 55 <ref bean="transactionTemplate" /> 56 </property> 57 </bean> 58 </beans>
第34至第40行是配置DataSourceTransactionManager信息,要为其装配一个dataSource.
如果是要配置Hibernate事务,要进行如下配置:(配置一个sessionFactory)
1 <!-- Hibernate事务管理器 --> 2 <bean id="transactionManager" 3 class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 4 <property name="sessionFactory"> 5 <ref bean="sessionFactory" /> 6 </property> 7 </bean>
看到上面第42到48行,配置了一个org.springframework.transaction.support.TransactionTemplate实例,要在代码中添加事务,Spring为我们提供了一种方法就是使用TransactionTemplate类。我们要为TransactionTemplate装配一个TransactionManager,如上所示。
使用TransactionTemplate进行事务管理:
1 package com.sunflower.dao; 2 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 6 import org.springframework.jdbc.core.JdbcTemplate; 7 import org.springframework.jdbc.core.RowCallbackHandler; 8 import org.springframework.transaction.TransactionStatus; 9 import org.springframework.transaction.support.TransactionCallback; 10 import org.springframework.transaction.support.TransactionTemplate; 11 12 import com.sunflower.entity.People; 13 14 /** 15 * @author Caihanyuan 16 * @time 2012-10-7 下午03:50:45 17 */ 18 public class BankDaoImp implements BankDao { 19 private JdbcTemplate jdbcTemplate; 20 private TransactionTemplate transactionTemplate; 21 22 public JdbcTemplate getJdbcTemplate() { 23 return jdbcTemplate; 24 } 25 26 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 27 this.jdbcTemplate = jdbcTemplate; 28 } 29 30 public TransactionTemplate getTransactionTemplate() { 31 return transactionTemplate; 32 } 33 34 public void setTransactionTemplate(TransactionTemplate transactionTemplate) { 35 this.transactionTemplate = transactionTemplate; 36 } 37 38 @Override 39 public double getMoney(final People people) { 40 double money = people.getMoney(); 41 // 开始事务,如果出现状况则回滚 42 transactionTemplate.execute(new TransactionCallback<People>() { 43 @Override 44 public People doInTransaction(TransactionStatus ts) { 45 try { 46 final People people2 = new People(); 47 // 使用JdbcTemplate进行持久化层操作 48 String sql = "select money from bank where name = ?"; 49 Object[] params = new Object[] { people.getName() }; 50 // 查询 51 jdbcTemplate.query(sql, params, new RowCallbackHandler() { 52 @Override 53 public void processRow(ResultSet rs) 54 throws SQLException { 55 people2.setMoney(rs.getDouble("money")); 56 System.out.println(people.getName() + "用户还有" 57 + rs.getDouble("money") + "元余款"); 58 System.out.println(people.getName() + "要从账户中取出" 59 + people.getMoney() + "元"); 60 if (people2.getMoney() < people.getMoney()) { 61 System.out.println("余额不足"); 62 people.setMoney(-1); 63 return; 64 } 65 } 66 }); 67 68 if (people.getMoney() < 0) 69 return null; 70 else { 71 sql = "update bank set money = ? where name = ?"; 72 Object[] params2 = new Object[] { 73 people2.getMoney() - people.getMoney(), 74 people.getName() }; 75 jdbcTemplate.update(sql, params2); 76 System.out.println("剩余余额:" 77 + (people2.getMoney() - people.getMoney())); 78 } 79 } 80 catch (Exception e) { 81 ts.setRollbackOnly(); 82 } 83 84 // 如果成功,事务被提交 85 return people; 86 } 87 }); 88 89 return people.getMoney(); 90 } 91 }
调用TransactionTemplate实例的execute()方法将执行包含在TransactionCallback实例里的代码。如果代码出现异常,调用TransactionStatus对象的setRollbackOnly()将事务回滚。否则,如果doInTransaction()方法正常返回,事务将被提交。
源代码下载:http://pan.baidu.com/share/link?shareid=81844&uk=2198762756
声明式事务:spring_声明式事务