事务管理

                                                                          事务管理

事务管理对企业来说是至关重要的,以便在程序出现异常情况下可以保证数据的完整性。对于纯JDBC的数据库操作,可以用以下代码进行事务管理。

获取连接 Connection con = DriverManager.getConnection()
    关闭/开启自动提交con.setAutoCommit(true/false);
    执行CRUD
    提交事务/回滚事务 con.commit() / con.rollback();
    关闭连接 conn.close();

若有异常:

} catch(SQLException sqle){            
         try{ 
             // 发生异常,回滚在本事务中的操做
            conn.rollback();
             // 事务回滚:转账的两步操作完全撤销
             stmt.close(); 
             conn.close(); 
         }catch(Exception ignore){ 

         }

spring事务管理
http://www.cnblogs.com/aliger/p/3898869.html
http://blog.csdn.net/liaohaojian/article/details/70139151
http://blog.csdn.net/wang0928007/article/details/7576591 数据库连接池形式的sping编程式事务管理(基于事务模板)

 spring提供编程式事务管理和声明式事务管理。spring事务管理的本质是数据库对事务的支持,没有数据库对事务的支持,spring是无法提供事务支持的。

spring编程式事务管理:两种spring编程式事务管理压根都没有使用AOP

不管是基于底层API还是基于模板,使用的都是相同的事务管理器类,都需要给事务管理器配置数据源。

用过 Hibernate 的人都知道,我们需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。通过 Spring 提供的事务管理 API,我们可以在代码中灵活控制事务的执行。在底层,Spring 仍然将事务操作委托给底层的持久化框架来执行。是否需要一个配置文件来配置这个委托?——持久层不用框架时只用jdbc的时候在配置文件中给事务管理器配一个数据源即可。

Spring 框架中,涉及到事务管理的 API 大约有100个左右,其中最重要的有三个:TransactionDefinition、PlatformTransactionManager、TransactionStatus。所谓事务管理,其实就是“按照给定的事务规则来执行提交或者回滚操作”。“给定的事务规则”就是用 TransactionDefinition 表示的,“按照……来执行提交或者回滚操作”便是用 PlatformTransactionManager 来表示,而 TransactionStatus 用于表示一个运行着的事务的状态。

TransactionDefination

用于定义一个事务。它包含了事务的静态属性,比如:事务隔离级别、事务传播行为、超时时间等等。Spring 为我们提供了一个默认的实现类:DefaultTransactionDefinition,该类适用于大多数情况。如果该类不能满足需求,可以通过实现 TransactionDefinition 接口来实现自己的事务定义。

 根据PlatformTransactionManager、TransactionDefinition 和 TransactionStatus 三个核心接口,我们完全可以通过编程的方式来进行事务管理。

基于底层API的编程式事务管理:

示例代码:

package service;

public class BasedOnAPIProgramming {
@Autowired
private AboutSql aboutSql;

public String callDaoMethod(String name){
return aboutSql.getQuan(name);
}
//编程式事务管理核心类
@Autowired
private PlatformTransactionManager manager;
public String callMethodOfDao(String quan,String name){
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
//启动事务(前提是获取事务定义类的实例并以该实例为参数传给启动事务的方法,可以用ioc获取也可以直接new来获取)
TransactionStatus status = manager.getTransaction(definition);
//启动事务代码执行后该行代码下面的代码直到事务提交前的代码全属于事务
String quanReturn="";
try {
aboutSql.updateRow(quan,name);
quanReturn = aboutSql.getQuan(name);
manager.commit(status);
} catch (TransactionException e) {
e.printStackTrace();
manager.rollback(status);
System.out.println("事务已回滚");
}
return quanReturn;
}
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 用来解析@Autowired注解 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<!-- 1.配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 用ioc配置service中用到的实例 -->
<bean id="basedOnAPIProgramming" class="service.BasedOnAPIProgramming">
</bean>

<!-- 被注入的对象(不论是注解还是别的方式)最后必须有对应的类 -->
<bean id="aboutSql" class="dao.AboutSql">
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="singleton">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:Oracle:thin:@localhost:1521:orcl"/>
<property name="username" value="SYSTEM"/>
<property name="password" value="0123654"/>
</bean>

 基于事务模板(TransactionTemplate)的编程式事务管理:

见项目

声明式事务管理:AOP的应用之一(基于AOP才有意义去谈通知,切点,连接点等(通过配置实现动态代理)。但AOP日志的例子网上为什么都没有使用xml配置切点,通知等方式而是使用编程方式)

 

编程式事务管理和声明式事务管理的区别:

1、表象上前者是在代码中使用注解来实现,后者则是通过配置文件来实现。

2、本质上

显然声明式事务管理优于编程式事务管理,spring提倡非侵入式的开发方式。

 声明式事务管理配置使用:(信保通项目使用声明式事务管理,详见mybatisContext.xml)

 

 http://blog.csdn.net/bao19901210/article/details/41724355

http://blog.csdn.net/u011726984/article/details/45421151

声明式事务管理建立在AOP之上,其本质是在方法前后进行拦截,在目标方法前创建或加入一个事务,在目标方法执行后根据执行情况提交或者回滚事务。声明式事务最大的优点是不需要通过编码的方式来管理事务,只需在配置文件中做相关的事务规则声明,或通过基于@Transactional注解的方式,便可将事务规则运用到业务逻辑中。

 声明式事务管理有两种常用方式,一种是基于tx和aop名字空间的xml配置文件,一种是基于@Transactional注解,显然基于注解的方式更简单??两种?

spring使用<tx:advice>和<aop:config>来配置声明式事务。?到底是一种还是两种?

spring声明式事务处理步骤:

1.引入tx和context命令空间

2.配置datasource

3.配置事务管理器

4.配置通知<tx:advice>,启用事务通知<aop:config>

 

 

 

 

在整个方法运行前就不会开启事务

还可以加上:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),这样就做成一个只读事务,可以提高效率。

“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。 

但是你非要在“只读事务”里面修改数据,也并非不可以,只不过对于数据一致性的保护不像“读写事务”那样保险而已。 

                                                                      事务的隔离级别

spring所有的事务管理策略继承自PlatformTransactionManager,而事务的隔离级别则由TransactionDefination来定义。TransactionDefination定义了五个表示隔离级别的常量。

isolation_read_committed:一个事务只能读取另一个事务已经提交的数据,这种隔离级别可以防止脏读。

isolation_default:默认值,同read_committed。

isolation_read_uncommitted:一个事务可以读取另一个事务修改但未提交的事务。此级别不能防止脏读,不可重复读和幻读,很少使用此隔离级别。

isolation_repeatable_read:一个事务在整个过程中可以多次执行某个查询且返回记录相同,可防止脏读和不可重复读。

isolation_serializable:所有事务要按次序依次执行,事务之间完全不干扰,但严重影响程序性能。

                                                                   Spring事务(在业务逻辑方法中)传播特性

事务传播行为就是指在某个业务逻辑的方法互相调用时,事务如何在这些方法中传递,它是业务逻辑的实现方法是否使用同一个事务的保证。

spring支持7种事务传播行为:

propagation_requierd:方法被调用时加入当前事务,如果当前没有事务则新建一个事务并开启。(最常见的选择)

propagation_supports:方法被调用时加入当前事务,如果当前没有事务则以非事务方法执行。

propagation_mandatory:方法被调用时加入当前事务,如果当前没有事务报异常。(必须在事务中执行的方法使用)

propagation_requierd_new:方法被调用时创建新事务,当前有事务则把当前事务挂起再新建。

propagation_not_supported:被调用时以非事务方法执行,当前有事务则把当前事务挂起,运行完毕后再恢复该事务。

propagation_never:以非事务方法执行,在事务范围内被调用时抛出异常。

propagation_nested:当前存在事务则在嵌套事务中执行,否则按requierd来执行。

                                                                    事务超时

事务超时指到了一个事务所允许执行的最长时间还没有完成该事务,则自动回滚事务。默认为底层数据库事务系统的超时值。

posted @ 2017-08-25 13:38  新生的小心情  阅读(211)  评论(0编辑  收藏  举报