Spring提供编程式的事务管理(Programmatic
transaction manage- ment)与声明式的事务管理(Declarative transaction
management),为不同的事务实现提供了一致的编程模型,这节以JDBC事务为例,介绍Spring的事务管理。
5.3.1 Spring对事务的支持
事务是一组原子(Atomic)操作的工作单元,以数据库存取的实例来说,就是一组SQL指令,这一组SQL指令必须全部执行成功,若因为某个原因未全部执行成功(例如其中一行SQL有错误),则先前所有执行过的SQL指令都会被撤消。
举个简单的例子,一个客户从A银行转账至B银行,要作的动作为从A银行的账户扣款、在B银行的账户加上转账的金额,两个动作必须成功,如果有一个动作失败,则此次转账失败。
事务还必须保持所参与资源的一致性(Consistent),例如在银行账户的例子中,两个账户的转账金额,B账户取款的金额不能大于A账户的存款金额。
每个事务彼此之间必须是隔离的(Isolated),例如在A账户中可能有两笔事务,同时进行存款与提款的动作,两个事务基本上不需意识到彼此的存在。事
务还必须是可持续的(Durable),在某一笔事务之后,这笔事务必须是被记录下来的。
在这里将介绍JDBC如何使用事务管理。首先来看看事务的原子性实现,在JDBC中,可以操作Connection的setAutoCommit()
方法,给定false参数,在下达一连串的SQL语句后,自行执行Connection的commit()来送出变更,如果中间发生错误,则执行
rollback() 来撤消所有的执行,例如:
try {
.....
connection.setAutoCommit(false);
.....
// 一连串SQL操作
connection.commit();
} catch(SQLException) {
// 发生错误,撤消所有变更
connection.rollback();
}
在Spring中对JDBC的事务管理加以封装,Spring事务管理的抽象关键在于org.springframework.transaction.PlatformTransactionManager接口的实现:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition
definition) throws TransactionException;
void commit(TransactionStatus status)
throws TransactionException;
void rollback(TransactionStatus status)
throws TransactionException;
}
PlatformTransactionManager
接口有许多具体的事务实现类,例如DataSourceTransactionManager、
HibernateTransactionManager、JdoTransaction-
Manager、JtaTransactionManager等,通过依赖于PlatformTransactionManager接口及各种的技术实
现,Spring在事务管理上可以让开发人员使用一致的编程模型,即使所使用的是不同的事务管理技术。
TransactionException是Unchecked Exception.事务的失败通常都是致命的错误,Spring不强迫您一定要处理,而是让您自行选择是否要捕捉异常。
getTransaction()
方法根据一个TransactionDefinition对象来回传一个TransactionStatus对
象,TransactionDefinition接口的实例定义了事务的隔离程度(Isolation
level)、传播行为(Propagation
behavior)、超时(Timeout)、只读(Read-only)等,TransactionStatus代表着一个新的事务发起或已经存在的事
务,您可以通过它来控制事务的执行或调查的状态:
public interface TransactionStatus {
boolean isNewTransaction();
void setRollbackOnly();
boolean isRollbackOnly();
}
Spring提供编程式的事务管理(Programmatic transaction management)与声明式的事务管理(Declarative transaction management):
l 编程式的事务管理
编程式的事务管理可以清楚地控制事务的边界,也就是让您自行实现事务开始时间、撤消操作的时机、结束时间等,可以实现细粒度的事务控制。
l 声明式的事务管理
然而多数的情况下,事务并不需要细粒度的控制,而是采用声明式的事务管理,好处是Spring事务管理的相关API可以不用介入程序之中,从对象的角度来
看,它并不知道自己正被纳入事务管理之中,在不需要事务管理的时候,只要在设置文件上修改一下设置,即可移去事务管理服务。
5.3.2
JDBC编程事务管理Spring提供两种方式实现编程式的事务管理,一是直接使用PlatformTransaction-
Manager实现,二是使用org.springframework.transaction.support.Transaction-
Template.
先来看看如何使用PlatformTransactionManager,在这里使用它的实现类
DataSourceTransactionManager,可以改写一下之前5.2.1节中的JdbcTemplateDemo项目,让它具有事务管理
功能,修改一下UserDAO类的insert() 方法来作示范:ProgrammaticTransactionDemo UserDAO.java
package onlyfun.caterpillar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.
datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.
support.DefaultTransactionDefinition;
public class UserDAO implements IUserDAO {
private DataSourceTransactionManager transactionManager;
private DefaultTransactionDefinition def;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
transactionManager =
new DataSourceTransactionManager(dataSource);
// 建立事务的定义
def = new DefaultTransactionDefinition();
def.setPropagationBehavior(
TransactionDefinition.PROPAGATION_REQUIRED);
}
public void insert(User user) {
String name = user.getName();
int age = user.getAge().intValue();
TransactionStatus status =
transactionManager.getTransaction(def);
try {
jdbcTemplate.update("INSERT INTO user (name,age) "
+ "VALUES('" + name + "'," + age + ")");
// 下面的SQL有错误,用以测试事务
jdbcTemplate.update("INSER INTO user (name,age) "
+ "VALUES('" + name + "'," + age + ")");
}
catch(DataAccessException e) {
transactionManager.rollback(status);
throw e;
}
transactionManager.commit(status);
}
public User find(Integer id) {
List rows = jdbcTemplate.queryForList(
"SELECT * FROM user WHERE id=" + id.intValue());
Iterator it = rows.iterator();
if(it.hasNext()) {
Map userMap = (Map) it.next();
Integer i = new Integer(
userMap.get("id").toString());
String name = userMap.get("name").toString();
Integer age = new Integer(
userMap.get("age").toString());
User user = new User();
user.setId(i);
user.setName(name);
user.setAge(age);
return user;
}
return null;
}
}
分享到:
相关推荐
实例详解Spring JDBC事务管理.doc 实例详解Spring JDBC事务管理.doc
两个项目,一个项目是基于spring jdbc实现的分布式事务,一个是基于spring hibernate的分布式事务,hibernate项目里的applicationContext2.xml是基于mysql和mssql, applicationContext3.xml基于两个mssql, ...
NULL 博文链接:https://hbiao68.iteye.com/blog/1608312
javaEE 实验三 Spring JDBC与事务管理, 一、实验目的 1、掌握Spring JDBC的配置; 2、掌握JdbcTemplae类中增删改查方法的使用; 3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握...
3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握基于XML和Annotation的声明式事务管理的使用。 二、 实验内容 1、在MySQL中创建以下三张表,其中account为账户表,book为书籍信息...
1、掌握Spring JDBC的配置; 2、掌握JdbcTemplae类中增删改查方法的使用;...3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握基于XML和Annotation的声明式事务管理的使用。
SpringJDBC注解事务.zip,SpringJDBC注解事务.zip
基于Spring JDBC的事务管理
spring声明式事务管理+jdbc+连接池 包内为代码,下载可直接执行。 一直用s2sh,感觉hibernate不好用,所以写了一个spring声明式事务管理+jdbc+连接池。
spring声明式事务管理+jdbc+连接池.zip
NULL 博文链接:https://kreding.iteye.com/blog/1680855
Spring集成的jdbc编码和事务管理
NULL 博文链接:https://zouhuiying.iteye.com/blog/2280681
Spring2.5+MySQL实现的JDBC操作(包括编程式事务的代码),如果有看不懂的地方可以去本人的博客:http://blog.csdn.net/Acceptedxukai,里面有具体讲解。
Spring JDBC Spring的JDBC模块负责数据库资源管理和错误处理,大大简化了开发人员对数据库的操作,使得开发人员可以从繁琐的数据库操作中解脱出来,从而将更多的精力投入到编写业务逻辑当中。 Spring JdbcTemplate...
Spring aop、jdbc和事务tx的学习,里面包含了三种的练习,都在不同的包内。
spring-jdbc.rar源码 学习分析用,了解jdbc内部原理,connection事务关系很有用
jdbc+spring+mysql事务理解和分析
注意:只是jdbc自带的jdbctample,不能 用于整合mybatis框架的事务,我整合了,事务不起作用!!!! 按老师的说法是基于xml方式,但不准确,因为也用到了注解 <aop:aspectj-autoproxy proxy-target-class="true">...
spring企业开发实战宝宝套项目maven配置实例,完成登陆操作,配置了事务,是学习利用maven管理springmvc+spring+springjdbc很好的小例子。