java spring 事务传播_spring事务传播机制实例讲解

天温习spring的事务处理机制,总结如下

对于SQL事务的概念以及ACID性质,可以参见我的另一篇博文 http://kingj.iteye.com/admin/blogs/1675011

spring的管理的事务可以分为如下2类:逻辑事务   在spring中定义的事务通常指逻辑事务,提供比物理事务更抽象,方便的事务配置管理,但也基于物理事务

物理事务  特定于数据库的事务

spring中支持一下2中事务声明方式编程式事务  当系统需要明确的,细粒度的控制各个事务的边界,应选择编程式事务

声明式事务  当系统对于事务的控制粒度较粗时,应该选择申明式事务

无论你选择上述何种事务方式去实现事务控制,spring都提供基于门面设计模式的事务管理器供选择,如下是spring事务中支持的事务管理器

事务管理器实现(org.springframework.*)

使用时机

jdbc.datasource.DataSourceTransactionManager

使用jdbc的抽象以及ibatis支持

orm.hibernate.HibernateTransactionManager

使用hibernate支持(默认3.0以下版本)

orm.hibernate3.HibernateTransactionManager

使用hibernate3支持

transaction.jta.JtaTransactionManager

使用分布式事务(分布式数据库支持)

orm.jpa.JpaTransactionManager

使用jpa做为持久化工具

orm.toplink.TopLinkTransactionManager

使用TopLink持久化工具

orm.jdo.JdoTransactionManager

使用Jdo持久化工具

jms.connection.JmsTransactionManager

使用JMS 1.1+

jms.connection.JmsTransactionManager102

使用JMS 1.0.2

transaction.jta.OC4JJtaTransactionManager

使用oracle的OC4J JEE容器

transaction.jta.WebLogicJtaTransactionManager

在weblogic中使用分布式数据库

jca.cci.connection.CciLocalTransactionManager

使用jrping对J2EE Connector Architecture (JCA)和Common Client Interface (CCI)的支持

UML结构图如下

95a6cd27bd78198f158947b590c81bf7.png

4、各种事务管理器的定义如下

JdbcTransactionManager定义如下

Xml代码 1e6ae5c932311fef755ac5ef738584aa.png

hibernate事务管理器配置如下

Xml代码 1e6ae5c932311fef755ac5ef738584aa.png

hibernate的事务管理器会注入session会话工厂,然后将事务处理委托给当前的transaction对象,事务提交时,调用commit()方法,回滚时调用rollback()方法

jpa事务管理器配置如下

Xml代码 1e6ae5c932311fef755ac5ef738584aa.png

其余事务管理器可参见spring in action中说明

5、申明式事务配置

spring特有的事务传播行为,spring支持7种事务传播行为,确定客户端和被调用端的事务边界(说得通俗一点就是多个具有事务控制的service的相互调用时所形成的复杂的事务边界控制)下图所示为7钟事务传播机制

传播行为

含义

PROPAGATION_REQUIRED(XML文件中为REQUIRED)

表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)

PROPAGATION_SUPPORTS(XML文件中为SUPPORTS)

表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行

PROPAGATION_MANDATORY(XML文件中为MANDATORY)

表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常

PROPAGATION_NESTED(XML文件中为NESTED)

表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同PROPAGATION_REQUIRED的一样

PROPAGATION_NEVER(XML文件中为NEVER)

表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常

PROPAGATION_REQUIRES_NEW(XML文件中为REQUIRES_NEW)

表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。

PROPAGATION_NOT_SUPPORTED(XML文件中为NOT_SUPPORTED)

表示该方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行

6、spring中的事务隔离级别

spring的事务隔离级别其实本质上是对SQL92标准的4种事务隔离级别的一种封装,具体参加我的博文:http://kingj.iteye.com/admin/blogs/1675011

spring的事务隔离级别如下表所示

隔离级别

含义

ISOLATION_DEFAULT

使用数据库默认的事务隔离级别

ISOLATION_READ_UNCOMMITTED

允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读

ISOLATION_READ_COMMITTED

允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生

ISOLATION_REPEATABLE_READ

对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生

ISOLATION_SERIALIZABLE

完全服从ACID隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。

7、spring事务只读属性

spring事务只读的含义是指,如果后端数据库发现当前事务为只读事务,那么就会进行一系列的优化措施。它是在后端数据库进行实施的,因此,只有对于那些有可能启动一个新事务的传播行为(REQUIRED,REQUIRES_NEW,NESTED)的方法来说,才有意义。(测试表明,当使用JDBC事务管理器并设置当前事务为只读时,并不能发生预期的效果,即能执行删除,更新,插入操作)

8、spring的事务超时

有的时候为了系统中关键部分的性能问题,它的事务执行时间应该尽可能的短。因此可以给这些事务设置超时时间,以秒为单位。我们知道事务的开始往往都会发生数据库的表锁或者被数据库优化为行锁,如果允许时间过长,那么这些数据会一直被锁定,影响系统的并发性。

因为超时时钟是在事务开始的时候启动,因此只有对于那些有可能启动新事物的传播行为(REQUIRED,REQUIRES_NEW,NESTED)的方法来说,事务超时才有意义。

9、事务回滚规则

spring中可以指定当方法执行并抛出异常的时候,哪些异常回滚事务,哪些异常不回滚事务。

默认情况下,只在方法抛出运行时异常的时候才回滚(runtime exception)。而在出现受阻异常(checked exception)时不回滚事务,这个ejb的回滚行为一致。

当然可以采用申明的方式指定哪些受阻异常像运行时异常那样指定事务回滚。

10、spring申明式事务配置

将aop,tx命名空间添加到当前的spring配置文件头中

定义一个事务AOP通知

Xml代码 1e6ae5c932311fef755ac5ef738584aa.png

定义一个事务切面,即应该在哪些类的哪些方法上面进行事务切入

Xml代码 1e6ae5c932311fef755ac5ef738584aa.png

11、结合具体的代码实现讲解spring的7种事务传播机制效果

准备环境

我们采用JDBC+ORACLE实现具体操作,首先搭建好spring的开发环境,配置好数据源,建立好Test

创建数据库结构,创建一个用户表和Book表

Sql代码 1e6ae5c932311fef755ac5ef738584aa.png

CREATE TABLE T_USER(

ID INT,

NAME VARCHAR2(200)

);

CREATE TABLE T_BOOK(

ID INT ,

NAME VARCHAR2(200)

);

搭建好的结构如下

8c2283dfc3c8fba292cfc4bc81faa718.png

Xml代码 1e6ae5c932311fef755ac5ef738584aa.png

destroy-method="close">

在spring包下面建立3个service

BookService

Java代码 1e6ae5c932311fef755ac5ef738584aa.png

package com.zx.spring;

import org.springframework.jdbc.core.JdbcTemplate;

public class BookService {

public static final String ADD_BOOK="insert into t_book(id,name) values(1,'duck-j2ee')";

private JdbcTemplate jdbcTemplate;

public void addBook() throws Exception{

this.jdbcTemplate.execute(ADD_BOOK);

throw new RollbackException("跳出执行");

}

public JdbcTemplate getJdbcTemplate() {

return jdbcTemplate;

}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

this.jdbcTemplate = jdbcTemplate;

}

}

UserService

Java代码 1e6ae5c932311fef755ac5ef738584aa.png

package com.zx.spring;

import org.springframework.jdbc.core.JdbcTemplate;

public class UserService {

public static final String ADD_USER="insert into t_user(id,name) values(1,'duck')";

private BookService bs;

private JdbcTemplate jdbcTemplate;

public void addUser()throws Exception {

this.bs.addBook();

this.jdbcTemplate.execute(ADD_USER);

}

public JdbcTemplate getJdbcTemplate() {

return jdbcTemplate;

}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

this.jdbcTemplate = jdbcTemplate;

}

public BookService getBs() {

return bs;

}

public void setBs(BookService bs) {

this.bs = bs;

}

}

创建一个ServiceFacade门面,将UserService和BookService包装起来

Java代码 1e6ae5c932311fef755ac5ef738584aa.png

package com.zx.spring;

public class ServiceFacade {

private BookService bs;

private UserService us;

public BookService getBs() {

return bs;

}

public void setBs(BookService bs) {

this.bs = bs;

}

public UserService getUs() {

return us;

}

public void setUs(UserService us) {

this.us = us;

}

public void addUserBook()throws Exception{

bs.addBook();

us.addUser();

}

}

上面我们配置了3个service接口,并在spring中配置了申明式事务。

Xml代码 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值