Spring学习8-Spring事务管理(AOP/声明式式事务管理)

一、基础知识普及
声明式事务的事务属性:

一:传播行为
二:隔离级别
三:只读提示
四:事务超时间隔
五:异常:指定除去RuntimeException其他回滚异常。
 传播行为:
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。

spring的事务传播规则:


传播行为


意义


PROPAGATION_REQUIRED


如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。


PROPAGATION_REQUIRES_NEW


创建一个新的事务,如果当前存在事务,则把当前事务挂起。


PROPAGATION_SUPPORTS


如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。


PROPAGATION_NOT_SUPPORTED


以非事务方式运行,如果当前存在事务,则把当前事务挂起。


PROPAGATION_NEVER


以非事务方式运行,如果当前存在事务,则抛出异常


PROPAGATION_MANDATORY


如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。


PROPAGATION_NESTED


如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;
如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

这里需要指出的是,前面的六种事务传播行为是 Spring 从
EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED是 Spring 所特有的。以
PROPAGATION_NESTED
启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起
内部事务的提交,嵌套的子事务不能单独提交。如果熟悉 JDBC
中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中可以包括多个保存点,每一个嵌套
子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。
隔离级别:
隔离级别是指若干个并发的事务之间的隔离程度:

spring的事务隔离级别: 


隔离级别


含义


ISOLATION_DEFAULT


这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是ISOLATION_READ_COMMITTED。


ISOLATION_READ_UNCOMMITTED


该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。


ISOLATION_READ_COMMITTED


该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。


ISOLATION_REPEATABLE_READ


该隔离级别表示一个事务在整个过程中可以多次重复执
行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。


ISOLATION_SERIALIZABLE


所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

只读提示:
SessionFlush设置为none
(readOnly);
事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、 JMS
资源,以及自定义的事务性资源等等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,以提高事务处理的性能。在
TransactionDefinition 中以 boolean 类型来表示该事务是否只读。

事务超时间隔:
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在
TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
声明式事务使用范例:
  
二、声明式事务配置的5中方式(方式四最常用)

   方式一、基于Spring1.x,使用TransactionProxyFactoryBean为每个Bean生成一个代理。

<?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:aop="http://www.springframework.org/schema/aop"
   
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<bean id="sessionFactory"
           
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="configLocation"
value="classpath:hibernate.cfg.xml" />
       
<property name="configurationClass"
value="org.hibernate.cfg.AnnotationConfiguration"
/>
   
</bean>

<!-- 定义事务管理器(声明式的事务) -->
   
<bean
id="transactionManager"      
class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"
/>
   
</bean>
  
   
<!-- 配置DAO省略 -->
   
<!--
*******业务逻辑层(是对各个DAO层的正面封装)主要用到<<门面模式>>******
-->
    
<bean id="fundService"
     
class="com.jack.fund.service.serviceimpl.FundService">

<property name="producedao">
      
<ref bean="fundProduceDAO" />
     
</property>
    
</bean>
  
    
<bean
id="fundServiceProxy"
     
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<!-- 配置事务管理器 -->
     
<property
name="transactionManager">
      
<ref bean="transactionManager"
/>
     
</property>
     
<!-- 此属性指定目标类本本身是否是代理的对象,如果目标类没有实现任何类,就设为true代表自己

可省略不写
-->
     
<property
name="proxyTargetClass">
      
<value>false</value>

</property>
     
<!-- 代理接口  可省略不写
-->
     
<property
name="proxyInterfaces">
      
<value>com.jack.fund.service.IFundService</value>

</property>
     
<!-- 目标bean -->
     
<property name="target">
      
<ref bean="fundService" />
     
</property>
     
<!-- 配置事务属性 -->
     
<property
name="transactionAttributes">
      
<props>
       
<prop
key="delete*">PROPAGATION_REQUIRED</prop>

<prop
key="add*">PROPAGATION_REQUIRED</prop>

<prop
key="update*">PROPAGATION_REQUIRED</prop>

<prop
key="save*">PROPAGATION_REQUIRED</prop>

<prop  
key="find*">PROPAGATION_REQUIRED,readOnly</prop>

</props>
     
</property>
    
</bean>

</beans>
    
可以看出它适用于你的库表比较少的情况下,针对每一个功能模块配置一个业务代理服务。如果模块多大话,就显得代码有点多了,发现他们只是稍微一点不一样。这时我们就应该想到继承的思想。用第二种方法。

方式二、基于Spring1.x,使用TransactionProxyFactoryBean为所有Bean共享一个代理基类。

<?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:aop="http://www.springframework.org/schema/aop"
   
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<bean id="sessionFactory"
           
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="configLocation"
value="classpath:hibernate.cfg.xml" />
       
<property name="configurationClass"
value="org.hibernate.cfg.AnnotationConfiguration"
/>
   
</bean>

<!-- 定义事务管理器(声明式的事务) -->
   
<bean id="transactionManager"
       
class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"
/>
   
</bean>
  
    
<!--
利用继承的思想简化配置,要把abstract="true"
-->
    
<bean
id="transactionBase"   
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

lazy-init="true" abstract="true">
     
<!-- 配置事务管理器 -->
     
<property
name="transactionManager">
      
<ref bean="transactionManager"
/>
     
</property>
     
<!-- 配置事务属性 -->
     
<property
name="transactionAttributes">
      
<props>
       
<prop
key="delete*">PROPAGATION_REQUIRED</prop>

<prop
key="add*">PROPAGATION_REQUIRED</prop>

<prop
key="update*">PROPAGATION_REQUIRED</prop>

<prop
key="save*">PROPAGATION_REQUIRED</prop>

<prop
key="find*">PROPAGATION_REQUIRED,readOnly</prop>

</props>
     
</property>
    
</bean>

   
<!--
而具体的模块可以简单的这样配置。只要指明它的parent(父类)就可以了。父类一般把abstract="true",因为在容器加载的时候不需要初始化,等到用的时候再有它的子类调用的时候,再去初始化。 
-->
  <!-- 配置DAO省略
-->
   
<!--
*******业务逻辑层(是对各个DAO层的正面封装)主要用到<<门面模式>>******
-->
    
<bean id="fundService"
     
class="com.jack.fund.service.serviceimpl.FundService">

<property name="producedao">
      
<ref bean="fundProduceDAO" />
     
</property>
    
</bean>
    <bean id="fundServiceProxy"
parent="transactionBase" >
     
<property name="target">
     
<ref bean="fundService" />
     
</property>
    
</bean>

</beans>
这样配置的话,如果有多个像fundService这样模块时,可以少些很多重复的代码。

方式三、基于SpringAOP的拦截器(主要利用BeanNameAutoProxyCreator自动创建事务代理)

<?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:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>

<bean id="sessionFactory"
           
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="configLocation"
value="classpath:hibernate.cfg.xml" />
       
<property name="configurationClass"
value="org.hibernate.cfg.AnnotationConfiguration"
/>
   
</bean>

<!-- 定义事务管理器(声明式的事务) -->
   
<bean id="transactionManager"
       
class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"
/>
   
</bean>
    <bean id="transactionInterceptor"
    
class="org.springframework.transaction.interceptor.TransactionInterceptor">

<property name="transactionManager"
ref="transactionManager" />
       
<!-- 配置事务属性 -->
     
<property
name="transactionAttributes">
      
<props>
       
<prop
key="delete*">PROPAGATION_REQUIRED</prop>

<prop
key="add*">PROPAGATION_REQUIRED</prop>

<prop
key="update*">PROPAGATION_REQUIRED</prop>

<prop
key="save*">PROPAGATION_REQUIRED</prop>

<prop
key="find*">PROPAGATION_REQUIRED,readOnly</prop>

</props>
     
</property>
   
</bean> 

<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<property name="beanNames">
           
<list>
           
<!-- 匹配所有的Service或者某个具体Service
-->
               
<value>*Service</value>

</list>
       
</property>
       
<property
name="interceptorNames">
           
<list>
               
<value>transactionInterceptor</value>

</list>
       
</property>
   
</bean>
    
<!-- 配置DAO省略 -->
   
<!--
*******业务逻辑层(是对各个DAO层的正面封装)主要用到<<门面模式>>******
-->
    
<bean id="fundService"
     
class="com.jack.fund.service.serviceimpl.FundService">

<property name="producedao">
      
<ref bean="fundProduceDAO" />
     
</property>
    
</bean>
</beans>

方式四、基于Spring2.x,使用tx标签配置的拦截器

<?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:aop="http://www.springframework.org/schema/aop"
   
xmlns:tx="http://www.springframework.org/schema/tx"
   
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
          
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean
id="sessionFactory"
     
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="configLocation"
value="classpath:hibernate.cfg.xml" />
       
<property name="configurationClass"
value="org.hibernate.cfg.AnnotationConfiguration"
/>
   
</bean>

<!-- 定义事务管理器(声明式的事务) -->
   
<bean id="transactionManager" 
class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"
/>
   
</bean>

<!--  
定义JDBC的事务管理器
     
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"
/>
   
</bean>

-->

<!-- 定义切面
-->
   
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
       
<tx:attributes>
           
<tx:method name="get*" read-only="true" rollback-for="java.lang.Exception"/>
                
<!--其他方法设为如下传播属性
-->
           
<tx:method name="*" propagation="REQUIRED"
rollback-for="java.lang.Exception"/>

</tx:attributes>
   
</tx:advice>

<!--
定义切点和织入
-->

  
    <aop:config>
       
<aop:pointcut id="interceptorPointCuts"
           
expression="execution(* com.spring.service.*.*(..))" />
       
<!--mgrService和empService省略 
-->
        
<aop:pointcut id="leePointcut"
     
     
expression="bean(mgrService) || bean(empService)"
/>
       
<aop:advisor advice-ref="txAdvice"
           
pointcut-ref="interceptorPointCuts"
/>
       
<aop:advisor advice-ref="txAdvice"
           
pointcut-ref="leePointcut"
/>
     
  <!-- 将authority转换成切面Bean
   
  
   
 切面Bean的新名称为:authorityAspect
-->
   
    <aop:aspect
id="authorityAspect" ref="authority">
   
  
   
 <!--
定义一个Around增强处理,直接指定切入点表达式
   
  
   
   
 以切面Bean中的authority()方法作为增强处理方法
-->
   
  
   
 <aop:around pointcut="execution(*
org.crazyjava.message.service.impl.*Impl.*Message*(..))"
   
  
   
   
 method="authority"/>
   
  
 </aop:aspect>
   
   
</aop:config>
<!-- 定义一个普通Bean实例,该Bean实例将进行权限控制
-->
   
<bean id="authority"
   
class="org.crazyjava.message.authority.AuthorityInterceptor"/>

</beans>

 关于权限拦截的类AuthorityInterceptor定义如下:
 public class AuthorityInterceptor
{
   
//进行权限检查的方法
    public
Object authority(ProceedingJoinPoint jp)
   
    throws
java.lang.Throwable
    {
   
    HttpSession
sess = null;
   
   
//获取被拦截方法的全部参数
   
    Object[]
args = jp.getArgs();
   
   
//遍历被拦截方法的全部参数
   
    for (int i =
0 ; i < args.length ; i++ )
   
    {
   
   
   
//找到HttpSession类型的参数
   
   
    if (args[i]
instanceof HttpSession) sess =
   
   
   
   
(HttpSession)args[i];
   
    }
   
   
//取出HttpSession里的user属性
   
    Integer
userId = (Integer)sess.getAttribute("user");
   
   
//如果HttpSession里的user属性不为null,且大于0
   
    if ( userId
!= null && userId >
0)
   
    {
   
   
    //继续处理
   
   
    return
jp.proceed(args);
   
    }
   
    else
   
    {
   
   
   
//如果还未登录,抛出异常
   
   
    throw new
MessageException("您还没有登陆,请先登陆系统再执行该操作");
   
    }
    }
}

方式五、注解式声明事务(详见下篇博文)

其实他们还可以混合使用,方式三和方式四的混合使用:
<?xml version="1.0"
encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
   
xmlns:aop="http://www.springframework.org/schema/aop"
   
xmlns:tx="http://www.springframework.org/schema/tx"
   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
   
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<!--   其他省略
   
   
********************
   
   
   
   AOP通知
   
   
********************
   
 -->
    <bean id="exception"
class="com.etc.advisor.ExceptionAdvisor"></bean>

<bean id="tx"
class="org.springframework.transaction.interceptor.TransactionInterceptor">

<constructor-arg index="0">
   
   
   
<ref bean="tm"/>
   
   
</constructor-arg>
   
   
<constructor-arg index="1">
   
   
   
<props>
   
   
   
   
<prop
key="*">PROPAGATION_REQUIRED</prop>

</props>
   
   
</constructor-arg>
   
</bean>
   
   
<aop:config
proxy-target-class="true">
   
   
<aop:pointcut id="p1" expression="(execution(*
com.etc.action.*.execute()))" />
   
   
<aop:pointcut id="p2" expression="(execution(*
com.etc.*.*.*(..)))" />
   
   
<aop:pointcut id="p3" expression="(execution(*
com.etc.service.*.*(..)))" /><!--
service的所有方法 -->
   
   
<aop:advisor advice-ref="tx"
pointcut-ref="p1"/>
   
   
<aop:advisor advice-ref="exception"
pointcut-ref="p2"/>
   
</aop:config>
</beans>

  
三、Spring事务配置示例

步骤一、配置文件(applicationContext.xml):
   
<?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"
    
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="userservice"
class="com.sunflower.yuan.serviceimp.UserServiceImp">

<property name="jdbcTemplate">
            
<ref bean="jdbcTemplate"/>
        
</property>
    
</bean>

<bean id="datasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName"
value="com.mysql.jdbc.Driver"></property>

<property name="url"
value="jdbc:mysql://localhost:3306/mytest"></property>

<property name="username"
value="root"></property>

<property name="password"
value="root"></property>

</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource">
            
<ref bean="datasource"/>
        
</property>
    
</bean>

<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">

<property name="dataSource">
            
<ref bean="mydatasource"/>
        
</property>
    
</bean>

  <bean
id="transactionAttributeSource"  
class="org.springframework.transaction.interceptor.
        
NameMatchTransactionAttributeSource">
        
<property name="properties">
            
<props>
                
<prop key="getMoney">
                    
PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-NoMoneyException
                
</prop>
            
</props>
        
</property>
    
</bean>

<!-- 声明式事务管理的代理类
-->
    
<bean
id="userTransaction"

class="org.springframework.transaction.interceptor.  
TransactionProxyFactoryBean">
        
<property
name="proxyInterfaces">
            
<list>
                
<value>com.sunflower.yuan.servicedao.UserService</value>

</list>
        
</property>
        
<property name="target">
            
<ref bean="userservice"/>
        
</property>
        
<property
name="transactionManager">
            
<ref bean="
transactionManager"/>

</property>
        
<property
name="transactionAttributeSource">
            
<ref
bean="transactionAttributeSource"/>
        
</property>
    
</bean>

 </beans>
声明式事务管理也是用动态代理模式来实现的,思想和AOP是一样的。主要是配置org.springframework.transaction.interceptor.TransactionProxyFactoryBean类。这个配置和AOP的配置非常相似。可以将事务属性单独写在org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource中,然后再用<property
name="transactionAttributeSource">引入,也可以直接用<property
name="transactionAttributes">配置事务属性。
<prop
key="getMoney">标签中的key="getMoney"表示对getMoney方法进行事务管理,也可使用通配符get*,表示对所有get前缀的方法进行事务管理。

事务属性的配置用","隔开,如下所示:

PROPAGATION, ISOLATION, readonly, -Exception, +Exception

PROPAGATION: 传播行为
ISOLATION: 隔离级别
readonly:  是否为只读事务(可选)
(+/-)Exception:  回滚规则。
如果是"-",遇到指定的Exception,事务回滚,如果是"+",事务不回滚。

UserService.java:

public interface UserService {
    
public void getMoney(int money, int id) throws
NoMoneyException;
 }

UserServiceImp.java:

package com.sunflower.yuan.serviceimp;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
 import
org.springframework.jdbc.core.JdbcTemplate;
 import
org.springframework.jdbc.core.RowCallbackHandler;
 
 import
com.sunflower.yuan.Exception.NoMoneyException;
 import
com.sunflower.yuan.servicedao.UserService;
 
 
 public class UserServiceImp implements
UserService {
    
private JdbcTemplate jdbcTemplate;
 
    
public JdbcTemplate getJdbcTemplate() {
        
return jdbcTemplate;
    
}
 
    
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        
this.jdbcTemplate = jdbcTemplate;
    
}
 
    
@Override
    
public void getMoney(int getMoney, int id) throws NoMoneyException
{
 
        
String sql = "select money from user where id=?";
        
Object[] params = new Object[] { new Integer(id) };
 
        
MyRowCallbackHandler rowCallBack = new
MyRowCallbackHandler();
        
jdbcTemplate.query(sql, params, rowCallBack);
 
        
if (rowCallBack.getMoney() > getMoney) {
            
sql = "update user set money=? where id=?";
            
Object[] params2 = new Object[] {
                    
rowCallBack.getMoney() - getMoney, new Integer(id) };
            
jdbcTemplate.update(sql, params2);
            
throw new NoMoneyException("余额不足");
        
}
 
    
}
 
    
class MyRowCallbackHandler implements RowCallbackHandler {
        
private int money = 0;
 
        
public int getMoney() {
            
return money;
        
}
 
        
public void setMoney(int money) {
            
this.money = money;
        
}
 
        
@Override
        
public void processRow(ResultSet rs) throws SQLException {
            
this.money = rs.getInt("money");
        
}
    
}
 }
这里要注意一点,要进行事务管理的方法,必须在方法外进行异常的抛出,这样事务管理器才能接收到,然后进行事务的回滚。如果用try-catch处理异常,将不会进行事务回滚。

借鉴博客地址:http://www.cnblogs.com/hanyuan/archive/2012/10/23/2732249.html

时间: 2024-10-14 00:39:54

Spring学习8-Spring事务管理(AOP/声明式式事务管理)的相关文章

Spring学习之Spring的声明式事务管理详解

声明式事务管理 大多数Spring用户选择声明式事务管理的原因是,这个是对应用代码影响最小的选择,因此也最符合 非侵入式 轻量级容器的理念. Spring声明式事务管理可以在任何环境下使用.只需更改配置文件, 它就可以和JDBC.JDO.Hibernate或其他的事务机制一起工作. Spring的声明式事务管理可以被应用到任何类(以及那个类的实例)上. Spring提供了声明式的回滚规则. Spring允许你通过AOP定制事务行为.(例如,如果需要,你可以在事务回滚中插入定制的行为. 你也可以增

spring学习笔记(23)基于tx/aop配置切面增强事务

在上一篇文章中,我们使用了声明式事务来配置事务,使事务配置从service逻辑处理中解耦出来.但它还存在一些缺点: 1. 我们只针对方法名的特定进行拦截,但无法利用方法签名的其它信息定位,如修饰符.返回值.方法入参.异常类型等.如果我们需要为同名不同参的同载方法配置不同事务就会出问题了. 2. 事务属性的配置串虽然能包含较多信息,但配置较易出错. 针对这些问题,我们可以基于Schema,引入tx和aop的命名空间来改进我们的配置: 引入命名空间 <beans xmlns="http://w

spring学习(三) ———— spring事务操作

前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTemplate? spring提供用于操作数据库模版,类似Dbutils,通俗点讲,我们操作数据库,spring也会帮我们提供一个操作数据库的工具供我们使用,而不用我们自己手动编写连接数据库,获取结果集等等操作,这个工具就是JdbcTemplate.跟Dbutils一样,想要使用JdbcTemplate

Spring学习总结(2)- AOP

一,什么是AOP AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 在学习AOP时,先要了解什么是代理模式,可以参考: 代理模式 二,使用Spring实现AOP

Spring学习4-面向切面(AOP)之schema配置方式

一.通过Scheme配置实现AOP步骤(Spring AOP环境的环境与上篇博文 Spring接口方式相同)    步骤一.编写业务类: public class AspectBusiness {    //切入点     public String delete(String obj) {         System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========\n");        

spring学习之aspectj的注解aop

基于aspectj的注解aop 1 使用注解方式实现aop操作 第一步 创建对象 第二步 在spring核心配置文件中,开启aop配置 第三步 在增强类上面使用注解完成aop操作 原文地址:https://www.cnblogs.com/czsy/p/10390181.html

Spring学习【Spring概述】

从本文开始,我们就要一起学习Spring框架,首先不得不说Spring框架是一个优秀的开源框架.其中采用IoC原理实现的基于Java Beans的配置管理和AOP的思想都是很值得学习与使用的.下面我们就进入正题!介绍Java平台上的一个优秀的开源应用框架Spring,以及Spring框架的历史和Spring框架相关基本知识. [转载使用,请注明出处:http://blog.csdn.net/mahoking] Spring 介绍 Spring是Java平台上的一个开源应用框架.它的第一个版本是由

spring学习9 Spring工作原理及其作用

1.springmvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作. 2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller. 3.DispatcherServlet请请求提交到目标Controller 4.Controller进行业务逻辑处理后,会返回一个ModelAndView 5.Dispathcher查询一个或多个ViewResolver视图解析器,找到Mo

Spring学习一----------Spring概况

Spring概况 Spring是为了解决企业应用开发的复杂性而创建的. Spring是一种轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. - 从大小和开销两方面而言Spring都是轻量的 - 通过控制反转(IOC)的技术达到松耦合的目的 - 提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发 - 包含并管理应用对象的配置和生命周期,这个意义上是一种容器 - 将简单的组件配置.组合成复杂的应用,这个意义上是框架 Spring作用 容器 提供了对多种技术