我的环境配置
Mysql :server version: 5.0.45-Debian_1ubuntu3.1-log Debian etch distribution
Spring frame: 2.0
jdk 1.6
数据库的配置:
要注意的问题:ENGINE=InnoDB
数据库映射对象类Order
实现RowMapper:
为了使用和扩展的方便使用了一些接口
以上是一些几本的类,下面就是一些和事务有关的具体实现了。
用于DAO的类:
业务逻辑类:
xml配置文件:
需要注意的是:
< property name ="defaultAutoCommit" >
< value > false </ value >
</ property >
最终的运行程序
如果要用TransactionTemplate这要注意异常捕获的位置和层次关系
以上运行后会抛出异常,并且数据库id变化,但是没有数据加入。这就是回滚机制的作用。
感谢spring为我们解决了很多。
Mysql :server version: 5.0.45-Debian_1ubuntu3.1-log Debian etch distribution
Spring frame: 2.0
jdk 1.6
数据库的配置:
--
MySQL Administrator dump 1.4
--
-- ------------------------------------------------------
-- Server version 5.0.45-Debian_1ubuntu3.1-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */ ;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */ ;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */ ;
/*!40101 SET NAMES utf8 */ ;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */ ;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */ ;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */ ;
--
-- Create schema SQLMapStudy
--
CREATE DATABASE IF NOT EXISTS SQLMapStudy;
USE SQLMapStudy;
--
-- Definition of table `SQLMapStudy`.`ORDER`
--
DROP TABLE IF EXISTS `SQLMapStudy`.` ORDER `;
CREATE TABLE `SQLMapStudy`.` ORDER ` (
`id` int ( 11 ) NOT NULL auto_increment,
` level ` int ( 11 ) default ' 0 ' ,
`name` text ,
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 42 DEFAULT CHARSET = latin1;
--
-- Dumping data for table `SQLMapStudy`.`ORDER`
--
/*!40000 ALTER TABLE `ORDER` DISABLE KEYS */ ;
LOCK TABLES ` ORDER ` WRITE;
INSERT INTO `SQLMapStudy`.` ORDER ` VALUES ( 24 , 5 , ' 233571 ' ),
( 25 , 3 , ' 237607 ' ),
( 26 , 4 , ' 951320 ' ),
( 27 , 4 , ' 3981449 ' ),
( 28 , 3 , ' 4201861 ' ),
( 29 , 3 , ' 4286204 ' ),
( 30 , 4 , ' 4467730 ' ),
( 31 , 4 , ' 4577921 ' ),
( 32 , 4 , ' 4644267 ' ),
( 33 , 4 , ' 4676767 ' ),
( 34 , 4 , ' 8718591 ' ),
( 35 , 4 , ' 1200488898355 ' ),
( 36 , 3 , ' 1200489291189 ' ),
( 37 , 3 , ' 1200489506119 ' ),
( 38 , 3 , ' 1200490058635 ' ),
( 41 , 4 , ' 1200490554236 ' );
UNLOCK TABLES;
/*!40000 ALTER TABLE `ORDER` ENABLE KEYS */ ;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */ ;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */ ;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */ ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */ ;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */ ;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */ ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */ ;
--
-- ------------------------------------------------------
-- Server version 5.0.45-Debian_1ubuntu3.1-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */ ;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */ ;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */ ;
/*!40101 SET NAMES utf8 */ ;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */ ;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */ ;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */ ;
--
-- Create schema SQLMapStudy
--
CREATE DATABASE IF NOT EXISTS SQLMapStudy;
USE SQLMapStudy;
--
-- Definition of table `SQLMapStudy`.`ORDER`
--
DROP TABLE IF EXISTS `SQLMapStudy`.` ORDER `;
CREATE TABLE `SQLMapStudy`.` ORDER ` (
`id` int ( 11 ) NOT NULL auto_increment,
` level ` int ( 11 ) default ' 0 ' ,
`name` text ,
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 42 DEFAULT CHARSET = latin1;
--
-- Dumping data for table `SQLMapStudy`.`ORDER`
--
/*!40000 ALTER TABLE `ORDER` DISABLE KEYS */ ;
LOCK TABLES ` ORDER ` WRITE;
INSERT INTO `SQLMapStudy`.` ORDER ` VALUES ( 24 , 5 , ' 233571 ' ),
( 25 , 3 , ' 237607 ' ),
( 26 , 4 , ' 951320 ' ),
( 27 , 4 , ' 3981449 ' ),
( 28 , 3 , ' 4201861 ' ),
( 29 , 3 , ' 4286204 ' ),
( 30 , 4 , ' 4467730 ' ),
( 31 , 4 , ' 4577921 ' ),
( 32 , 4 , ' 4644267 ' ),
( 33 , 4 , ' 4676767 ' ),
( 34 , 4 , ' 8718591 ' ),
( 35 , 4 , ' 1200488898355 ' ),
( 36 , 3 , ' 1200489291189 ' ),
( 37 , 3 , ' 1200489506119 ' ),
( 38 , 3 , ' 1200490058635 ' ),
( 41 , 4 , ' 1200490554236 ' );
UNLOCK TABLES;
/*!40000 ALTER TABLE `ORDER` ENABLE KEYS */ ;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */ ;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */ ;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */ ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */ ;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */ ;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */ ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */ ;
数据库映射对象类Order
/*
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
public class Order {
private int id;
private int level;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
public class Order {
private int id;
private int level;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/*
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class OrderRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int index) throws SQLException {
Order order = new Order();
order.setId(rs.getInt("id"));
order.setLevel(rs.getInt("level"));
order.setName(rs.getString("name"));
return order;
}
}
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class OrderRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int index) throws SQLException {
Order order = new Order();
order.setId(rs.getInt("id"));
order.setLevel(rs.getInt("level"));
order.setName(rs.getString("name"));
return order;
}
}
为了使用和扩展的方便使用了一些接口
package
com.studyspring.ch5;
import java.util.List;
public interface IUserDAO {
public List<Order> getUserList();
public Order makeOrder(String name);
public void changelevel(int userid);
}
// /
package com.studyspring.ch5;
public interface IUserManager {
public boolean processOrder(String name);
}
import java.util.List;
public interface IUserDAO {
public List<Order> getUserList();
public Order makeOrder(String name);
public void changelevel(int userid);
}
// /
package com.studyspring.ch5;
public interface IUserManager {
public boolean processOrder(String name);
}
以上是一些几本的类,下面就是一些和事务有关的具体实现了。
用于DAO的类:
/*
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
import java.util.List;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDAOImpl implements IUserDAO {
private String sql;
private JdbcTemplate jdbcTemplate;
public void changelevel(int userid) {
Object[] param = new Object[]{new Integer(userid)};
sql = "update `ORDER` set level=level+1 where id=?";
jdbcTemplate.update(sql,param);
}
public List<Order> getUserList() {
// TODO Auto-generated method stub
return null;
}
public Order makeOrder(String name) {
Order order = new Order();
Object[] param = new Object[]{new Integer(3),new String(name)};
sql="insert into `ORDER`"
+"(level,name) value"
+"(?,?)";
int rowcount = jdbcTemplate.update(sql, param);
if(rowcount==1){
sql="select * from `ORDER`";
List list = jdbcTemplate.query(sql, new OrderRowMapper());
order =(Order)list.get(list.size()-1);
}
throw new DataAccessResourceFailureException(sql);//如果要人为制造异常可以用这种方式抛出以检验回滚机制
//个人检测好象是任何异常都可以,这个任意是指:运行时异常还有spring的DataAccessResourceException的子类
//return order;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
import java.util.List;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDAOImpl implements IUserDAO {
private String sql;
private JdbcTemplate jdbcTemplate;
public void changelevel(int userid) {
Object[] param = new Object[]{new Integer(userid)};
sql = "update `ORDER` set level=level+1 where id=?";
jdbcTemplate.update(sql,param);
}
public List<Order> getUserList() {
// TODO Auto-generated method stub
return null;
}
public Order makeOrder(String name) {
Order order = new Order();
Object[] param = new Object[]{new Integer(3),new String(name)};
sql="insert into `ORDER`"
+"(level,name) value"
+"(?,?)";
int rowcount = jdbcTemplate.update(sql, param);
if(rowcount==1){
sql="select * from `ORDER`";
List list = jdbcTemplate.query(sql, new OrderRowMapper());
order =(Order)list.get(list.size()-1);
}
throw new DataAccessResourceFailureException(sql);//如果要人为制造异常可以用这种方式抛出以检验回滚机制
//个人检测好象是任何异常都可以,这个任意是指:运行时异常还有spring的DataAccessResourceException的子类
//return order;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
业务逻辑类:
/*
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.studyspring.ch3.Advice4Hello;
public class UserManagerImpl implements IUserManager {
private Log log = LogFactory.getLog(Advice4Hello.class);
private IUserDAO userDAO;
private PlatformTransactionManager manager;
public boolean processOrder(String name) {
DefaultTransactionDefinition td = new DefaultTransactionDefinition(
TransactionDefinition.PROPAGATION_REQUIRED);
td.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
td.setTimeout(500);
TransactionStatus status = manager.getTransaction(td);//记录回滚前状态
try{
Order order = userDAO.makeOrder(name);
userDAO.changelevel(order.getId());
log.info("The order level changing: "+order.getName());
}catch (DataAccessException e) {
manager.rollback(status);//启动回滚
log.warn("Order error");
throw e;
}
manager.commit(status);//正常结束,写数据库
return true;
}
public IUserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
public PlatformTransactionManager getManager() {
return manager;
}
public void setManager(PlatformTransactionManager manager) {
this.manager = manager;
}
}
* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
* Licensed to the Wang Pengcheng under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The LGPL licenses this file to You under the GNU Lesser General Public
* Licence, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Edit 15 Jan 2008
package com.studyspring.ch5;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.studyspring.ch3.Advice4Hello;
public class UserManagerImpl implements IUserManager {
private Log log = LogFactory.getLog(Advice4Hello.class);
private IUserDAO userDAO;
private PlatformTransactionManager manager;
public boolean processOrder(String name) {
DefaultTransactionDefinition td = new DefaultTransactionDefinition(
TransactionDefinition.PROPAGATION_REQUIRED);
td.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
td.setTimeout(500);
TransactionStatus status = manager.getTransaction(td);//记录回滚前状态
try{
Order order = userDAO.makeOrder(name);
userDAO.changelevel(order.getId());
log.info("The order level changing: "+order.getName());
}catch (DataAccessException e) {
manager.rollback(status);//启动回滚
log.warn("Order error");
throw e;
}
manager.commit(status);//正常结束,写数据库
return true;
}
public IUserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
public PlatformTransactionManager getManager() {
return manager;
}
public void setManager(PlatformTransactionManager manager) {
this.manager = manager;
}
}
xml配置文件:
需要注意的是:
< property name ="defaultAutoCommit" >
< value > false </ value >
</ property >
<?
xml version="1.0" encoding="UTF-8"
?>
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >
< bean id ="dataSource"
class ="org.apache.commons.dbcp.BasicDataSource"
destroy-method ="close" >
< property name ="driverClassName" >
< value > com.mysql.jdbc.Driver </ value >
</ property >
< property name ="url" >
< value > jdbc:mysql://localhost:3306/SpringStudy </ value >
</ property >
< property name ="username" >
< value > mysql user name </ value >
</ property >
< property name ="password" >
< value > mysql password </ value >
</ property >
< property name ="defaultAutoCommit" >
< value > false </ value >
</ property >
</ bean >
< bean id ="jdbcTemplate"
class ="org.springframework.jdbc.core.JdbcTemplate" >
< property name ="dataSource" >
< ref local ="dataSource" />
</ property >
</ bean >
< bean id ="transactionManager"
class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
< property name ="dataSource" >
< ref local ="dataSource" />
</ property >
</ bean >
< bean id ="userOimpl" class ="com.studyspring.ch5.UserDAOImpl" >
< property name ="jdbcTemplate" >
< ref local ="jdbcTemplate" />
</ property >
</ bean >
< bean id ="userManager"
class ="com.studyspring.ch5.UserManagerImpl" >
< property name ="userDAO" >
< ref local ="userOimpl" />
</ property >
< property name ="manager" >
< ref local ="transactionManager" />
</ property >
</ bean >
</ beans >
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >
< bean id ="dataSource"
class ="org.apache.commons.dbcp.BasicDataSource"
destroy-method ="close" >
< property name ="driverClassName" >
< value > com.mysql.jdbc.Driver </ value >
</ property >
< property name ="url" >
< value > jdbc:mysql://localhost:3306/SpringStudy </ value >
</ property >
< property name ="username" >
< value > mysql user name </ value >
</ property >
< property name ="password" >
< value > mysql password </ value >
</ property >
< property name ="defaultAutoCommit" >
< value > false </ value >
</ property >
</ bean >
< bean id ="jdbcTemplate"
class ="org.springframework.jdbc.core.JdbcTemplate" >
< property name ="dataSource" >
< ref local ="dataSource" />
</ property >
</ bean >
< bean id ="transactionManager"
class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
< property name ="dataSource" >
< ref local ="dataSource" />
</ property >
</ bean >
< bean id ="userOimpl" class ="com.studyspring.ch5.UserDAOImpl" >
< property name ="jdbcTemplate" >
< ref local ="jdbcTemplate" />
</ property >
</ bean >
< bean id ="userManager"
class ="com.studyspring.ch5.UserManagerImpl" >
< property name ="userDAO" >
< ref local ="userOimpl" />
</ property >
< property name ="manager" >
< ref local ="transactionManager" />
</ property >
</ bean >
</ beans >
最终的运行程序
package
com.studyspring.ch5;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class PogrammaticTrans {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"/src/com/studyspring/ch5/configch5.xml");
IUserManager userManager = (IUserManager) ctx.getBean("userManager");
System.err.print(userManager.processOrder(Long.toString(System.currentTimeMillis())));
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class PogrammaticTrans {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"/src/com/studyspring/ch5/configch5.xml");
IUserManager userManager = (IUserManager) ctx.getBean("userManager");
System.err.print(userManager.processOrder(Long.toString(System.currentTimeMillis())));
}
}
如果要用TransactionTemplate这要注意异常捕获的位置和层次关系
package
com.studyspring.ch5;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.studyspring.ch3.Advice4Hello;
public class UserManagerImplWTT implements IUserManager {
private Log log = LogFactory.getLog(Advice4Hello.class);
private IUserDAO userDAO;
private PlatformTransactionManager manager;
public boolean processOrder(final String name) {
TransactionTemplate tt = new TransactionTemplate(manager);
tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
tt.setTimeout(500);
try {
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Order order = new Order();
order = userDAO.makeOrder(name);
userDAO.changelevel(order.getId());
log.info("Finish :" + order.getName());
return order;
}
});
} catch (Exception e) {
//添加这个捕获的原因是:一般我们不会将异常抛给系统,而是利用AOP进行统一处理。
//如果在 doInTransaction里面捕获则不会回滚。
}
return true;
}
public IUserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
public PlatformTransactionManager getManager() {
return manager;
}
public void setManager(PlatformTransactionManager manager) {
this.manager = manager;
}
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.studyspring.ch3.Advice4Hello;
public class UserManagerImplWTT implements IUserManager {
private Log log = LogFactory.getLog(Advice4Hello.class);
private IUserDAO userDAO;
private PlatformTransactionManager manager;
public boolean processOrder(final String name) {
TransactionTemplate tt = new TransactionTemplate(manager);
tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
tt.setTimeout(500);
try {
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Order order = new Order();
order = userDAO.makeOrder(name);
userDAO.changelevel(order.getId());
log.info("Finish :" + order.getName());
return order;
}
});
} catch (Exception e) {
//添加这个捕获的原因是:一般我们不会将异常抛给系统,而是利用AOP进行统一处理。
//如果在 doInTransaction里面捕获则不会回滚。
}
return true;
}
public IUserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
public PlatformTransactionManager getManager() {
return manager;
}
public void setManager(PlatformTransactionManager manager) {
this.manager = manager;
}
}
以上运行后会抛出异常,并且数据库id变化,但是没有数据加入。这就是回滚机制的作用。
感谢spring为我们解决了很多。