首页 > 代码库 > 声明式事务管理

声明式事务管理

目前运用得比较广泛的有两种声明式事务管理,一种是@Transactional,另一种是在配置文件中做相关的规则事务说明。

这里呢,我就直接给大家讲讲@Transactional声明式事务管理吧。配置文件的声明式事务管理参考http://www.design63.com.cn/showsite_1725.html

由于是同一个项目,所以我就不一一将代码呈现出来了,大家可以参考上面的超链接,谢谢。

我们直接进入到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"  
        xmlns:aop="http://www.springframework.org/schema/aop"   
        xmlns:context="http://www.springframework.org/schema/context"  
        xmlns:jee="http://www.springframework.org/schema/jee"  
        xmlns:tx="http://www.springframework.org/schema/tx"  
        xsi:schemaLocation="    
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd  
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
    <!-- 类似于财务部门一样,类就是钱,所有需要类的实例都由srping去管理 -->
    <!-- <context:component-scan>:
        有一个use-default-filters属性,该属性默认为true,
        这就意味着会扫描指定包下的全部的标有注解的类,并注册成bean.
        可以发现这种扫描的粒度有点太大,如果你只想扫描指定包下面的Controller,
        该怎么办?此时子标签<context:incluce-filter>就起到了勇武之地。如下所示
        <context:component-scan base-package="news" use-default-filters="false">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
        如果use-dafault-filters在上面并没有指定,默认就为true,
        也就意味着你现在加<context:exclude-filter/>跟没加是一样的
        所有你要记住,你若想要用到<context:component-scan>的子标签,
        必须要把use-dafault-filters的值改为false
        当然还有一个是与之相反的而已这里就不啰嗦了
        上面这一对解释换成一句话就是:
            Use-dafault-filters=”false”的情况下:<context:exclude-filter>指定的不扫描,<context:include-filter>指定的扫描
    <context:component-scan>的base-package属性作用:设置要被扫描的包 -->
    
    <!-- (本案例不用到,只是用了一个全盘扫描,以上内容只是为了让大家了解它) -->
    
    <context:component-scan base-package="news.."/>
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- <tx:annotation-driven transaction-manager="transactionManager"/> -->

    <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="http://www.mamicode.com/${jdbc.driver}"/>
        <property name="jdbcUrl" value="http://www.mamicode.com/${jdbc.url}"/>
        <property name="user" value="http://www.mamicode.com/${jdbc.user}"/>
        <property name="password" value="http://www.mamicode.com/${jdbc.password}"/>
        <!-- 每300秒检查所有连接池中的空闲连接 -->
        <property name="idleConnectionTestPeriod" value="http://www.mamicode.com/300"/>
        <!-- 最大空闲时间,900秒内未使用则连接被丢弃。若为0则永不丢弃 -->
        <property name="maxIdleTime" value="http://www.mamicode.com/900"/>
        <!-- 最大连接数 -->
        <property name="maxPoolSize" value="http://www.mamicode.com/2"/>
    </bean>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <!-- <property name="packagesToScan">
            <list>
                这里value值添实体类所在的包
                <value>news.entity</value>
            </list>
        </property> -->
        <property name="mappingResources">
            <list>
                <value>news/entity/News.hbm.xml</value>
            </list>
        </property>
    </bean>
    
    <bean id="transactionManager" 
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
         <!--  创建事务管理器, 管理sessionFactory(因为所有的session都是从sessionFactory获取的) -->
         <property name="sessionFactory" ref="sessionFactory" />
     </bean>
     <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

接着我们来看看serviceImpl这边,如下所示:

package news.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import news.dao.Newsdao;
import news.entity.News;
@Service
@Scope("prototype")
public class NewsServiceImpl implements NewsService {
    @Autowired
    private Newsdao nd;
    @Transactional(readOnly=true)
    public List<News> showAll(){
        List<News> listAllNews=nd.showAll();
        return listAllNews;
    }
    @Transactional(propagation=Propagation.REQUIRED)
    public String delSingleNews(Integer id){
        String deleteList=nd.delSingleNews(id);
        return deleteList;
    }
}

这个展示的结果和上一篇的是一样的。

既然一样,那我们来看看他们有什么不同的地方吧。

我的理解就是如果是大型项目的话还是建议用配置文件的声明式事务管理,为什么这么说呢?

首先,大型的项目他所定义的类定义的方法有很多,这也就需要声明,但是如果用的是配置文件的声明事务管理的话就只需要改配置文件中所对应的方法就可以了。

相反,如果还是用注解式的事务管理的话会造成忘记写注解而导致的错误,虽然用注解的方式在速度上有点优势,但是也不全对。说到这里,你是否真的理解了这两种的区别了?

 用官方的话来说他们的区别,如下:

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

以上就是我的理解,仅供参考~.~

声明式事务管理