spring事务管理全解析

spring事务管理全解析

了解事务:
        事务是一组原子(Atomic)操作的工作单元,以数据库存取的实例来说,就是一组SQL指令,这一组SQL指令必须全部执行成功,若因为某个原因未全部执行成功(例如其中一行SQL有错误),则先前所有执行过的SQL指令都会被撤消。 

JDBC是如何控制事务的

spring事务管理全解析try {

spring事务管理全解析
spring事务管理全解析    …..
spring事务管理全解析
spring事务管理全解析    connection.setAutoCommit(false);
spring事务管理全解析
spring事务管理全解析    …..
spring事务管理全解析
spring事务管理全解析    // 一连串SQL操作
spring事务管理全解析
spring事务管理全解析    connection.commit();
spring事务管理全解析
spring事务管理全解析}
 catch(SQLException) {

spring事务管理全解析
spring事务管理全解析    // 发生错误,撤消所有变更
spring事务管理全解析
spring事务管理全解析    connection.rollback();
spring事务管理全解析
spring事务管理全解析}

spring事务管理全解析
spring事务管理全解析
Spring是把JDBC事务管理进来了封装,Spring事务管理的抽象关键在于org.springframework.transaction.PlatformTransactionManager接口

里面有 commit 和 rollback 

spring事务管理全解析public interface PlatformTransactionManager {

spring事务管理全解析
spring事务管理全解析    TransactionStatus getTransaction(TransactionDefinition 
spring事务管理全解析
spring事务管理全解析                    definition)  throws TransactionException;
spring事务管理全解析
spring事务管理全解析    void commit(TransactionStatus status) 
spring事务管理全解析
spring事务管理全解析                                   throws TransactionException;
spring事务管理全解析
spring事务管理全解析    void rollback(TransactionStatus status) 
spring事务管理全解析
spring事务管理全解析                                   throws TransactionException;
spring事务管理全解析
spring事务管理全解析}

spring事务管理全解析
spring事务管理全解析
TransactionDefinition接口的实例定义了
事务的隔离程度(Isolation level)
传播行为(Propagation behavior)
超时(Timeout)
只读(Read-only)等

DataSourceTransactionManager、HibernateTransactionManager、JdoTransaction- Manager、JtaTransactionManager等是实现了该接口

Spring提供编程式的事务管理(Programmatic transaction management)与声明式的事务管理(Declarative transaction management):

1、编程式的事务管理可以清楚地控制事务的边界,也就是让您自行实现事务开始时间、撤消操作的时机、结束时间等,可以实现细粒度的事务控制。

 

2、然而多数的情况下,事务并不需要细粒度的控制,而是采用声明式的事务管理,好处是Spring事务管理的相关API可以不用介入程序之中,从对象的角度来看,它并不知道自己正被纳入事务管理之中,在不需要事务管理的时候,只要在设置文件上修改一下设置,即可移去事务管理服务。

 

 

声明式的事务管理举例  以DataSource,mysql举例

 

spring事务管理全解析          < bean  id =”dataSource”  

spring事务管理全解析                class =”org.springframework.jdbc.datasource.DriverManagerDataSource”

spring事务管理全解析                  destroy-method =”close” >   

spring事务管理全解析

spring事务管理全解析             < property  name =”driverClassName”  value =”com.mysql.jdbc.Driver” />  

spring事务管理全解析    

spring事务管理全解析             < property  name =”url”  value =”jdbc:mysql://localhost:3306/demo” />

spring事务管理全解析    

spring事务管理全解析             < property  name =”username”  value =”caterpillar” />  

spring事务管理全解析    

spring事务管理全解析             < property  name =”password”  value =”123456″ />  

spring事务管理全解析

spring事务管理全解析         </ bean >  

spring事务管理全解析

spring事务管理全解析    

spring事务管理全解析

spring事务管理全解析         < bean  id =”transactionManager”  

spring事务管理全解析              class =”org.springframework.jdbc.datasource.DataSourceTransactionManager” >  

spring事务管理全解析              

spring事务管理全解析             < property  name =”dataSource”  ref =”dataSource” />  

spring事务管理全解析            

spring事务管理全解析         </ bean >  

spring事务管理全解析

spring事务管理全解析    

spring事务管理全解析

spring事务管理全解析         < bean  id =”userDAO”  class =”onlyfun.caterpillar.UserDAO” >

spring事务管理全解析    

spring事务管理全解析             < property  name =”dataSource”  ref =”dataSource” />

spring事务管理全解析    

spring事务管理全解析         </ bean >

spring事务管理全解析

spring事务管理全解析    

spring事务管理全解析

spring事务管理全解析         < bean  id =”userDAOProxy”  

spring事务管理全解析            class =”org.springframework.transaction.interceptor.TransactionProxyFactoryBean” >  

spring事务管理全解析

spring事务管理全解析         < property  name =”proxyInterfaces” >  

spring事务管理全解析             < list >

spring事务管理全解析                 < value > onlyfun.caterpillar.IUserDAO </ value >

spring事务管理全解析             </ list >

spring事务管理全解析         </ property >  

spring事务管理全解析

spring事务管理全解析         < property  name =”target”  ref =”userDAO” />  

spring事务管理全解析

spring事务管理全解析         < property  name =”transactionManager”  ref =”transactionManager” />  

spring事务管理全解析

spring事务管理全解析         < property  name =”transactionAttributes” >  

spring事务管理全解析

spring事务管理全解析             < props >  

spring事务管理全解析

spring事务管理全解析                 < prop  key =”insert*” > PROPAGATION_REQUIRED </ prop >  

spring事务管理全解析

spring事务管理全解析             </ props >  

spring事务管理全解析

spring事务管理全解析         </ property >         

spring事务管理全解析

spring事务管理全解析            </ bean >     

 

TransactionProxyFactoryBean需要一个TransactionManager,由于这里使用的是JDBC,所以使用DataSourceTransactionManager,TransactionProxyFactoryBean是个代理对象,”target” 属性指定要代理的对象,事务管理会自动介入指定的方法前后,这里使用 “transactionAttributes” 属性指定,”insert*” 表示指定方法名称以insert开头的都要纳入事务管理,您也可以指定方法全名,如果在方法执行过程中发生错误,则所有先前的操作自动撤回,否则正常提交。

在”insert*” 等方法上指定了 “PROPAGATION_REQUIRED”,表示在目前的事务中执行操作,如果事务不存在就建立一个新的,相关的常数意义都可以在API文件的TransactionDefinition接口中找到。您可以加上多个事务定义,中间使用逗号 “,” 区隔,例如可以加上只读,或者是指定某个异常发生时撤回操作:

PROPAGATION_REQUIRED,readOnly,-MyCheckedException

MyCheckedException前面加上 “-” 时,表示发生指定异常时撤消操作,如果前面加上 “+”,表示发生异常时立即提交。

由于”userDAO”被”userDAOProxy”代理了,所以要做的是取得”userDAOProxy”,而不是”userDAO”,

 

spring事务管理全解析         IUserDAO userDAO  =  

spring事务管理全解析

spring事务管理全解析            (IUserDAO) context.getBean( ” userDAOProxy ” );

spring事务管理全解析

spring事务管理全解析        userDAO.insert(user);

spring事务管理全解析

 

申明式事务管理一般都是粗粒度的,这里可以看到,整个方法都被纳入事务管理,其实在大部分的业务处理中,这样做是没有什么不好的。

 

事务的属性介绍

传播行为

 说明

PROPAGATION_MANDATORY

方法必须在一个现存的事务中进行,否则丢出异常

PROPAGATION_NESTED

在一个嵌入的事务中进行,如果不是,则同PROPAGATION_REQUIRED

PROPAGATION_NEVER

指出不应在事务中进行,如果有就丢出异常

PROPAGATION_NOT_SUPPORTED

指出不应在事务中进行,如果有就暂停现存的事务

PROPAGATION_REQUIRED

支持现在的事务,如果没有就建立一个新的事务

PROPAGATION_REQUIRES_NEW

建立一个新的事务,如果现存一个事务就暂停它

PROPAGATION_SUPPORTS

支持现在的事务,如果没有就以非事务的方式执行

隔离层级

说明

ISOLATION_DEFAULT

使用底层数据库预设的隔离层级

ISOLATION_READ_COMMITTED

允许事务读取其他并行的事务已经送出(Commit)的数据字段,可以防止Dirty read问题

ISOLATION_READ_UNCOMMITTED

允许事务读取其他并行的事务还没送出的数据,会发生Dirty、Nonrepeatable、Phantom read等问题

续表

隔离层级

说明

ISOLATION_REPEATABLE_READ

要求多次读取的数据必须相同,除非事务本身更新数据,可防止Dirty、Nonrepeatable read问题

ISOLATION_SERIALIZABLE

完整的隔离层级,可防止Dirty、Nonrepeatable、Phantom read等问题,会锁定对应的数据表格,因而有效率问题

 只读提示(Read-only hints)

如果事务只进行读取的动作,则可以利用底层数据库在只读操作时发生的一些最佳化动作,由于这个动作利用到数据库在只读的事务操作最佳化,因而必须在事务中才有效,也就是说要搭配传播行为PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED来设置。

 

事务超时期间(The transaction timeout period)

有的事务操作可能延续很长一段的时间,事务本身可能关联到数据表格的锁定,因而长时间的事务操作会有效率上的问题,对于过长的事务操作,您要考虑Roll back事务并要求重新操作,而不是无限时的等待事务完成。

您可以设置事务超时期间,计时是从事务开始时,所以这个设置必须搭配传播行为PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED来设置。

(上面是从《spring2.0技术开发》摘抄的,里面有些概念还含糊不清,有待实验考证下)

这里我来介绍一种新的模式,不知道大家有没有用到过,在文档中没有发现

spring事务管理全解析    <bean id=”txProxyTemplate” abstract=”true” class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
spring事务管理全解析        <property name=”transactionManager”><ref local=”transactionManager”/></property>
spring事务管理全解析        <property name=”transactionAttributes”>
spring事务管理全解析            <props>
spring事务管理全解析                <prop key=”add*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”create*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”update*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”delete*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”license*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”save*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”increase*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”active*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”modify*”>PROPAGATION_REQUIRED</prop>
spring事务管理全解析                <prop key=”*”>PROPAGATION_REQUIRED,readOnly</prop>
spring事务管理全解析            </props>
spring事务管理全解析        </property>
spring事务管理全解析    </bean>    
我在这里不去指定target  那么去哪里指定呢?

spring事务管理全解析    <bean id=”providerServiceTarget” class=”cn.com.zjtelecom.mall.service.pojo.ProviderService” />
spring事务管理全解析    <bean id=”providerService” parent=”txProxyTemplate” >
spring事务管理全解析        <property name=”target”><ref local=”providerServiceTarget”/></property>    
spring事务管理全解析    </bean>
这里的意图,大家只有非常了解代理模式才会明白其中的道理。那么分开设置有什么好处呢?模块化,大家可以公用这个代理模式,而且可以定义自己的声明,和其他人的声明无关。

 

参考:

http://dev.firnow.com/course/3_program/java/javajs/2007923/73069.html

http://www.cnblogs.com/kelin1314/archive/2009/11/25.html

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100484.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c++虚函数详解(你肯定懂了)

    c++虚函数详解(你肯定懂了)转自:c++虚函数 大牛的文章,就是通俗易懂,言简意赅。前言C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议…

    2022年7月26日
    11
  • tcp数据包最大长度(udp数据包最大长度)

    在tcp数据包处理的实战中,总会确定payload的长度但是呢,tcp头部中没有确定的tcp_len长度,非常的烦所以一般如下确定payload长度:从IP报头(IP.len)中提取“总长度”,然后减去“IP报头长度”(IP.len)。hdrlen)和“TCP头长度”(TCP。hdrlen)。在内核中也就是ip->tot_len-ip->len-hdr_len(tcp)。…

    2022年4月15日
    48
  • esp32显示屏_1602a液晶屏显示不了

    esp32显示屏_1602a液晶屏显示不了文章记录了本硬件小白尝试使用ESP32芯片点亮1602A屏幕

    2022年9月22日
    3
  • salt的grains工具和pillar工具使用详解

    salt的grains工具和pillar工具使用详解什么是 grains 工具 Salt 附带一接口 用于获取有关底层系统的信息 Salt 的 grains 主要存储静态数据 用来收集 minion 端的一些数据 比如 操作系统 域名 IP 地址 内核 操作系统类型 内存或者其他系统属性 Minion 端在启动时会读取 grains 数据 如果有新的 grains 数据需要重启 minion 服务或者在 master 端使用 salt 命令进行刷新一 minion 端的 roles 之前

    2025年8月11日
    6
  • windows远程桌面和teamviewer_windows远程桌面端口

    windows远程桌面和teamviewer_windows远程桌面端口Windows的远程桌面输错了一次密码,然后就怎么都连接不上了,查了半天发现傻缺360会默认屏蔽Windows的远程桌面和数据库连接…..大家没事都卸载了360吧转载于:https://www.cnblogs.com/JiangOil/p/10561828.html…

    2025年11月19日
    6
  • go微服务框架go-micro深度学习(二) 入门例子

    go微服务框架go-micro深度学习(二) 入门例子

    2021年6月13日
    322

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号