spring2.0事务处理
spring的事务管理,实际上是将jdbc操作的繁琐代码做成了切面.
引言:传统的jdbc编程的缺点:
如:使用jdbc完成插入一条记录
1 2 3 4 5 6 7 | 代码1 ...// 核心业务代码 psmt.executeUpdate(sql) ;// 代码2 |
如上所示,为了执行一条SQL语句,我们写了许多的繁锁的代码(代码1,代码2),但这是jdbc编程所必须的,
spring的事务处理就是 : 将{代码1}和{代码2}做成了切面,开发人员只要写和业务逻辑相关的代码即可,
图片如下所示:

1. Spring提供了两种事务处理方式
(1) 编程式的
(2) 声明式的(基于Spring的AOP原理)
这里推荐使用第二种方式,因为这样可以使业务层和spring最小程度的耦合
2. 下面以添加用户为例来分别演示两种方式操作事务
3. 新建一个项目,导入以下jar包: commons-logging.jar , log4j-1.2.14.jar , spring.jar, mysql-connector-java-3.1.14-bin.jar
4. 使用编程式事务处理:
(1) 新建一个POJO类:User.java
(2) 创建操作user的接口和实现类: IUserDAO.java , UserDAOImpl2.java
(3) 编写spring配置文件applicationContext.xml
(4) 编写测试类:Test2.java
(5) 运行结果:
(1) 新建一个POJO类:User.java
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
package cn.koma.business.pojo;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 8777636556392100355L;
private Long id;
private String username;
private String password;
public User() {
super();
}
public User(Long id) {
super();
this.id = id;
}
// setter && getter
}
(2) 创建操作user的接口和实现类: IUserDAO.java , UserDAOImpl2.java
package cn.koma.business.dao;
import cn.koma.business.pojo.User;
/**
*
* @author Administrator
* 业务逻辑层:操作user
*/
public interface IUserDAO {
public User addUser(User user) ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
package cn.koma.business.dao;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import cn.koma.business.pojo.User;
public class UserDAOImpl2 implements IUserDAO {
// 事务管理者
private PlatformTransactionManager transactionManger;
// 被spring容器注入
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public User addUser(final User user) {
// 1.simple data check
if (!this.simpleCheck(user))
return null;
User result = null;
// 3.call jdbcTemplate to insert
// (1)get the DefintionTransaction
TransactionTemplate transactionTemplate = new TransactionTemplate(
this.transactionManger);
// (2)begin transaction
result = (User) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
String sql = "insert into user (username , password) values(?,?)";
// update db
jdbcTemplate.update(sql, new Object[] { user.getUsername(),
user.getPassword() });
// query id
sql = "select max(id) from user";
Long id = jdbcTemplate.queryForLong(sql);
user.setId(id);
return user;
}
});
// 5.return result
return result;
}
// simple data check
private boolean simpleCheck(User user) {
if (user == null)
return false;
String username = user.getUsername();
String password = user.getPassword();
if (username == null || "".equals(username))
return false;
if (password == null || "".equals(password))
return false;
return true;
}
public PlatformTransactionManager getTransactionManger() {
return transactionManger;
}
public void setTransactionManger(
PlatformTransactionManager transactionManger) {
this.transactionManger = transactionManger;
}
}
|
(3) 编写spring配置文件applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://192.168.1.196:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>
<!-- 配置PlatformTransactionManager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- 采用编程式事务处理 -->
<bean id="userDAO2" class="cn.koma.business.dao.UserDAOImpl2">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate" />
</property>
<property name="transactionManger">
<ref bean="transactionManager" />
</property>
</bean>
</beans>
|
(4) 编写测试类:Test2.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
package cn.koma.test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import cn.koma.business.dao.IUserDAO;
import cn.koma.business.pojo.User;
public class Test2 {
public static void main(String[] args) {
// 1.加载spring配置文件
BeanFactory factory = new FileSystemXmlApplicationContext(
"applicationContext.xml");
// 2.得到userDAO实例
IUserDAO userDAO = (IUserDAO) factory.getBean("userDAO2");
// 3.调用userDAO添加user
User user = new User();
user.setUsername("koma2");
user.setPassword("123456");
user = userDAO.addUser(user);
if (user == null)
return;
System.out.println("id : " + user.getId());
System.out.println("username : " + user.getUsername());
System.out.println("password : " + user.getPassword());
}
}
|
(5) 运行结果:
1 2 3 4 |
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
id : 4
username : koma2
password : 123456
|
5. 使用声明式事务处理:
(1) 新建一个POJO类:User.java
代码同上
(2) 创建操作user的接口和实现类: IUserDAO.java , UserDAOImpl.java
IUserDAO.java代码同上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
package cn.koma.business.dao;
import org.springframework.jdbc.core.JdbcTemplate;
import cn.koma.business.pojo.User;
public class UserDAOImpl implements IUserDAO {
// 被spring容器注入
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public User addUser(User user) {
// 1.simple data check
if (!this.simpleCheck(user))
return null;
// 2.create sql
String username = user.getUsername();
String password = user.getPassword();
String sql = "insert into user (username , password) values(?,?)";
// 3.call jdbcTemplate to insert
this.jdbcTemplate.update(sql, new Object[] { username, password });
// 4.query the id
sql = "select max(id) from user";
Long id = jdbcTemplate.queryForLong(sql);
user.setId(id);
// 5.return result
return user;
}
// simple data check
private boolean simpleCheck(User user) {
if (user == null)
return false;
String username = user.getUsername();
String password = user.getPassword();
if (username == null || "".equals(username))
return false;
if (password == null || "".equals(password))
return false;
return true;
}
}
|
(3) 编写spring配置文件applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://192.168.1.196:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>
<!-- 配置PlatformTransactionManager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- 配置userDAO -->
<!-- 采用声明式事务处理 -->
<bean id="userDAO" class="cn.koma.business.dao.UserDAOImpl">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate" />
</property>
</bean>
<!-- 使用代理,外界只要知道它就行了 -->
<bean id="userDAOProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<!-- 设置事务的属性定义 -->
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<!-- 配置代理目标 -->
<property name="target">
<ref bean="userDAO" />
</property>
</bean>
</beans>
|
关于spring事务属性的配置,可以参考这篇文章:http://klyuan.javaeye.com/blog/78674?page=3
(4) 编写测试类:Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
package cn.koma.test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import cn.koma.business.dao.IUserDAO;
import cn.koma.business.pojo.User;
public class Test {
public static void main(String[] args) {
// 1.加载spring配置文件
BeanFactory factory = new FileSystemXmlApplicationContext(
"applicationContext.xml");
// 2.得到userDAO实例
IUserDAO userDAO = (IUserDAO) factory.getBean("userDAOProxy");
// 3.调用userDAO添加user
User user = new User();
user.setUsername("koma");
user.setPassword("123456");
user = userDAO.addUser(user);
if (user == null)
return;
System.out.println("id : " + user.getId());
System.out.println("username : " + user.getUsername());
System.out.println("password : " + user.getPassword());
}
}
|
(5) 运行结果:
1 2 3 4 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////
id : 5
username : koma1
password : 123456 |
6. 可以看出 , 使用声明式事务处理 , 让我们的代码可以尽量少的与spring耦合
7. spring在jdk5.0之后,支持@AspectJ,可以使用注解来配置事务,读者可以参考相关文章