spring框架中的事务管理
来源:互联网 发布:金日十数据 编辑:程序博客网 时间:2024/04/30 10:31
一、概述
(一)基本概念
1 、什么是Spring事务处理?
什么是事务处理我就不想回答了。 Spring 的事务处理,可以说是 Spring AOP 的一种实现。因为事务处理是所谓方面( Aspect )的一个子集。因此默认情况下,事务处理是利用 Java 动态代理机制实现的,这样就必须先定义一个接口,然后再编写实现;而对于没有接口的 Javabean ,则通过 CGLIB 实现。这部分是 Spring AOP 部分的内容。
2 、两种事务处理方式
和 EJB 一样, Spring 也提供两种事务处理方式,一种是编程式事务处理;一种是声明式事务处理。
(二)框架图
实现事务处理的两种方式
Java 动态代理
CGLIB
两种事务处理方式
编程式事务处理
声明式事务处理
(三)何时使用什么
如果需要大量的事务处理,就用声明式事务处理,如果很少的事务处理,就用编程式
二、详细
编程式事务处理与声明式事务处理
(一)编程式事务处理
1 、使用TransactionTemplate进行事务处理(Spring进行commit和rollback)
( 1 )使用事务处理的类
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.dao.*;
public class bookDAO{
private DataSource dataSource;// 依赖注入 dataSource ,管理数据库
private PlatformTransationManager transactionManager;// 依赖注入管理事务
public void setDataSource(DataSource dataSource){
this.dataSource=dataSource;
}
public void setTransactionManager(PlatformTransationManager transactionManager){
this. transactionManager= transactionManager;
}
public int create(String msg){
TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);
// 调用 transactionTemplate 的 execute 方法进行事务管理
Object result= transactionTemplate.execute (
// 这是一个回调函数,实现了 TransactionCallback 接口的 doInTransaction 方法,就是在这个方法里写数据库新增数据的操作
new TransactionCallback()
{
public Object doInTransaction(TransactionStatus status)
{
// 数据库操作代码
return resultObject;
}
}
[U1] )
}
}
如果不想返回结果( resultObject ),则可以用 TransactionCallbackWithoutResult 来实现 TransactionCallback 接口,代码如下:
new TransactionCallback WithoutResult ()
{
public Object doInTransaction WithoutResult (TransactionStatus status)
{
// 数据库操作代码
}
}
( 2 )配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!— 设 定dataSource à
<bean id=”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
<!— 使用SQL Server 数 据 库 à
<property name=”driverClassName”>
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<property name=”url”>
<value>jdbc:Microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<property name=”name”>
<value>admin</value>
</property>
<property name=”msg”>
<value>admin</value>
</property>
</bean>
<!— 设定 transactionManager à
<bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource”>
<ref bean=”dataSource”/>
</property>
</bean>
<!— 示例中 DAO-->
<bean id=”bookDAO” class=”com.bookDAO”>
<property name=”dataSource”>
<ref bean=”dataSource”/>
</property>
<property name=”transactionManager”>
<ref bean=”transactionManager”>
</property>
</bean>
</beans>
这样 Spring 就可以自动进行 commit 和 rollback 这两个操作了。粉色部分是为了和 bookDAO 中的粉色部分相匹配。
2 、使用JdbcTemplate进行事务处理(硬编码进行commit和rollback)
( 1 )使用事务处理的类
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.dao.*;
public class bookDAO{
private DataSource dataSource;// 依赖注入 dataSource ,管理数据库
private PlatformTransationManager transactionManager;// 依赖注入管理事务
public void setDataSource(DataSource dataSource){
this.dataSource=dataSource;
}
public void setTransactionManager(PlatformTransationManager transactionManager){
this. transactionManager= transactionManager;
}
public int create(String msg){
/* TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);
Object result= transactionTemplate.execute (
new TransactionCallback()
{
public Object doInTransaction(TransactionStatus status)
{
return resultObject;
}
}
)*/
// 使用下面的代码替换上面注释掉的部分
DefaultTransactionDefinition def =new DefaultTransactionDefinition();
TransactionStatus status=transactionManager.getTransaction(def);
try
{
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
jdbcTemplate.update(“INSERT INTO book VALUES(1,’gf’,’Mastering Spring’)”);
}
catch(DataAccessException ex)
{
transactionzManager.rollback(status);
throw ex;
}
finally
{
transactionManager.commit(status);
}
}
}
( 2 )配置文件
同上
( 二)声明式事务处理
( 1 )使用事务处理的类
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.dao.*;
public class bookDAO{
private DataSource dataSource;// 依赖注入 dataSource ,管理数据库
private PlatformTransationManager transactionManager;// 依赖注入管理事务
public void setDataSource(DataSource dataSource){
this.dataSource=dataSource;
}
public void setTransactionManager(PlatformTransationManager transactionManager){
this. transactionManager= transactionManager;
}
public int create(String msg){
① /* TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);
Object result= transactionTemplate.execute (
new TransactionCallback()
{
public Object doInTransaction(TransactionStatus status)
{
return resultObject;
}
}
)*/
② /* DefaultTransactionDefinition def=new DefaultTransactionDefinition();
TransactionStatus status=transactionManager.getTransaction(def);
try
{
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
jdbcTemplate.update(“INSERT INTO book VALUES(1,’gf’,’Mastering Spring’)”);
}
catch(DataAccessException ex)
{
transactionzManager.rollback(status);
throw ex;
}
finally
{
transactionManager.commit(status);
} */
// 使用下面的代码替换上面注释掉的部分
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
jdbcTemplate.update(“INSERT INFO book VALUES(1,’gf’,’Mastering Spring’)”);
/ / 与 ② 相比,此段代码省去了 commit 和 rollback 事务处理语句;与 ① 相比,不必实现 TransactionCallback 接口
}
}
( 2 )配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!— 设 定dataSource à
<bean id=”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
<!— 使用SQL Server 数 据 库 à
<property name=”driverClassName”>
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<property name=”url”>
<value>jdbc:Microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<property name=”name”>
<value>admin</value>
</property>
<property name=”msg”>
<value>admin</value>
</property>
</bean>
<!— 设定 transactionManager à
<bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource”>
<ref bean=”dataSource”/>
</property>
</bean>
<!— 示例中 DAO-->
<bean id=”bookDAO” class=”com.bookDAO”>
<property name=”dataSource”>
<ref bean=”dataSource”/>
</property>
<!— 与编程式事务处理相比,在 DAO 设置中去掉了这个属性,把它放到了代理类中。 - à
<!— <property name=”transactionManager”>
<ref bean=”transactionManager”>
</property> - à
</bean>
<!— 声明式事务处理 - à
<bean id=”bookDAOProxy” class=”org.springframework.transaction.interceptor.Transation.ProxyFactoryBean”>
<property name=”transacionManager”>
<ref bean=”transacionMaganer”/>
</property>
<property name=”target”>
<ref bean=”bookDAO”/>
</property>
<property name=”transactionAttributes”>
<props>
<!-- 表示对 bookDAO 中的 create 方法进行事务处理,并指明当前没有事务就新建一个(用 PROPAGATION_REQUIRED 常量来表示的) à
<prop key=”create * ”>PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
续:
事务管理是企业级应用程序中必不可少的一项技术,用于确保数据的完整性和一致性。
作为企业级应用程序框架,Spring在不同的事务管理API上定义了一个抽象层。
程序员不必太了解底层的事务管理API,就能使用Spring事务管理机制。
如同EJB中的BMT(Bean-managed transaction,Bean管理事务)和CMT(Container-managed transaction,容器管理事务)方法一样,Spring即支持编程式的事务管理也支持声明式的事务管理。Spring事务支持的目标是给POJO添加事务功能,提供一种EJB事务的可选方法。
编程式事务管理:是将事务管理代码嵌入到业务方法中来控制事务的提交和回滚。如果方法正常完成,通常会提交事务;如果方法抛出某种类型的异常,则回滚事务。
然而在使用编程式事务管理时,必须在每个事务操作中包含另外的事务管理代码。因此要在每个操作中重复样板事务代码。此外还很难对不同的应用程序启用和禁用事务管理。事务管理是横切关注点。
声明式事务管理:在大多数情况下要比编程式事务管理更好用。它将事务管理代码从业务中分离出来,以声明的方式来实现事务管理。事务管理作为一种横切关注点,可以通过AOP方法模块化。Spring同Spring AOP框架支持声明式事务管理。这样可以帮助你更加轻松的为应用程序启用事务,并定义一致的事务策略。然而,声明式事务管理不太灵活,因为无法通过代码精确的控制事务。
事务属性:
原子性
一致性
隔离性
持久性
1.选择事务管理器实现
问题:一般情况下,如果应用程序只涉及单个数据源,可以只在数据库连接上调用commit()和rollback()方法来管理事务。
然而,如果事务扩展到多个数据源,或者你更喜欢使用JavaEE应用服务器提供的事务管理功能,就可以选择JTA(Java Transaction API,Java事务API)。此外,你可能还需要为不同的对象/关系映射框架(如:Hibernate或JPA)调用不同专用事务API。
因此,必须为不同的技术处理不同的事务API。很难从一组API切换到另一组API。
实现方案:PlateformTransactionManager是所有Spring事务管理器的通用接口。Spring内置了几个实现,用于不同事物管理API。
如果在应用程序中只需要处理一个数据源,并且通过JDBC进行存取,DataSourceTransactionManager应该满足需求。
如果在JavaEE应用服务器上涌JTA进行事务管理,就应该使用JtaTransactionManager从应该服务器查找事务。
如果使用ORM存取数据库,并且通过JDBC进行存取,就应该选取相应的事务管理器。
事务管理器以普通Bean的形式声明在SpringIoC容器里。例如,下面的Bean配置声明了一个DataSourceTransactionManager实例。
它需要设置dataSource属性,以便可以对这个数据源上的连接进行事务管理。
2.用事务管理器API编程式地管理事务
3.用事务模板编程式地管理事务
4.用经典的Spring AOP声明式地管理事务
问题:事务管理是一种横切关注点,AOP是实现它的理想方法。然而,如果要在Spring1.x中声明式地管理事务,就必须使用经典Spring AOP方法。
解决方案:Spring为事务管理提供了一个环绕通知,称作TransactionInterceptor。这个通知像事务模板一样控制这事务管理流程,但它使用于整个方法体,而不是任意的代码块。默认情况下,在方法开始之前,这个通知就启动了一个新的事务。如果方法抛出未受检的异常,上午就被回滚。否则完成方法之后就提交事务。
在经典Spring AOP中,必须利用ProxyFactoryBean为Bean创建一个代理来应用TransactionInterceptor通知。由于事务管理在企业应用中非常普遍,因此Spring提供了一个TransactionProxyFactoryBean类,它专用于创建事务代理。
Dao类:
Spring IoC容器:
Main类:
5.用事务通知声明式的管理事务
Main类:
6.用@Transactional注解声明式地管理事务
Spring IoC容器:
7.设置传播事务属性
问题描述:当事务方法别另一个方法调用时,必须制定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能启动一个新事务,并在它自己的事务中运行。
解决方法:事务的传播行为可以由传播事务属性制定。Spring定义了7种传播行为,这些行为时在org.springframework.transaction.TransactionDefinition中定义的。并非所有事务管理器类型都支持这些传播行为。
- spring框架中的事务管理
- Spring框架中的事务管理
- [Spring]Spring中的事务管理
- spring框架的事务管理
- Spring框架的事务管理
- Spring6:Spring中的事务管理
- Spring中的事务管理
- spring中的事务管理
- Spring中的事务管理方式
- Spring 中的事务管理
- Spring中的事务管理
- Spring中的事务管理
- Spring 中的事务管理
- Spring中的事务管理方式
- Spring中的事务管理
- Spring中的事务管理
- Spring 中的事务管理
- Spring 中的事务管理
- Leetcode Single Number
- Catch all type exceptions programming Android
- 集社交与金融为一体,平安天下通如何推动互联网金融创新?
- java中volatile关键字的含义
- ios基础知识
- spring框架中的事务管理
- Redis 在新浪微博中的应用
- 使用heartbeat+monit实现主备双热备份系统
- NSString 值传不进问题,报optimized out错误
- Android源码目录结构
- isAssignableFrom与instanceof的区别
- openwrt安装luci-app-pbx后无LUCI界面的解决方法
- Logback学习笔记
- Redis命令