spring声明式事务管理

前言:

  敲着敲着几遍ssh框架,发现越来越有趣了,难道我喜欢上了这个框架?喜欢的话先了解它,然后懂得它,为它着想,接着喜欢上它,与自己融为一体。那么,我什么时候我喜欢上了这个框架呢?可能就是一看到这个框架哪里生病(报错),就能立即在它身边照顾它(解决报错),让它少吃上火的东西(简化代码)。。。。哈哈哈哈,可能这就是有些程序员喜欢new一个对象。程序小白先new一个对象,先熟悉这个对象,然后练敲代码(刚开始认识对象),沟通了一段时间后成为程序新手(和对象开始恋爱),接着成为程序员(热恋中),最后成为架构师(白头偕老)。【以上纯属个人瞎想】

续上篇:  

  先讲一下声明式事务:

  声明式事务(declarative transaction management)是spring提供的对程序事务管理的方式之一。事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。
COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。
ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有以完成的操作全部撤消,滚回到事务开始的状态

  之前我们在dao里面写下了事务:

public class NewsDaoImpl implements NewsDao {
       public List showAllNews() {
        Session session = sf.openSession();
        //Session session = sf.getCurrentSession();
        session.getTransaction().begin();
        
        Query query = session.createQuery("from News");

        /*List<News> allNewList = new ArrayList<News>();*/
        
        List<News> allNewList  = query.getResultList();
        
        session.getTransaction().commit();
        session.close();
    
        return allNewList;
    }              
}

 可能大家一开始看觉得没什么,但是当你频繁调用这个方法时,你每次都要打开一个Session,每次都需要事务开始(session.getTransaction().begin();),事务提交(session.getTransaction().commit();),还有就是每次都要关闭Session,频繁的做这些事情,耗能耗时又不符合我们的软件工程思想,这个时候就用到声明式事务管理方式进行对代码的简化和调整:

首先 

在配置文件添加:

<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="mod*" propagation="REQUIRED" />
            <tx:method name="*" propagation="REQUIRED" read-only="true" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="interceptorPointCuts"
            expression="execution(*   
        news.dao.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
    </aop:config>

然后把Dao里面的方法修改(本例以查询方法):

public class NewsDaoImpl implements NewsDao {
          public List showAllNews() {

        Session session = sf.getCurrentSession();
        Query query = session.createQuery("from News");
        List<News> allNewList  = query.getResultList();

        
        //Session session = sf.openSession();//每一次,都创建1个新的session
        //session.getTransaction().begin();
        /*List<News> allNewList = new ArrayList<News>();*/
        //session.getTransaction().commit();
        //session.close();
    
        return allNewList;
    }
}

将原来的openSession()方法改为了getCurrentSession()方法。

最后别忘了导几个包呦

aopalliance-1.0
 aspectjrt
 aspectjweaver
 cglib-nodep-2.1_3

注解驱动:

首先在配置文件删除

<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="del*" propagation="REQUIRED" />
			<tx:method name="mod*" propagation="REQUIRED" />
			<tx:method name="*" propagation="REQUIRED" read-only="true" />
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<aop:pointcut id="interceptorPointCuts"
			expression="execution(*   
        news.dao.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
	</aop:config>

  

在配置文件添加:<tx:annotation-driven transaction-manager="transactionManager"/>

然后再NewsServiceImpl加注解,可能有些博友会问为什么不是在NewsDaoImpl加注解呢?回答:哪里调用就哪里写。

@Transactional注解可以添加到类上:所有的方法都加入事务管理

@Transactional注解也可以写在单独方法

@Override
    @Transactional(readOnly=true)
    public List showAllNews() {
        //可以增加一个业务逻辑,比如:把文章的内容进行截取为20字符
        //通过DAO获取数据
        List<News> allNewList = nd.showAllNews();
        //在return 之间,可以进行各种业务逻辑操作
        
        return allNewList;
    }

总结(笔记):

   1)SpringAOP声明式事务管理低耦合,可读性低,灵活性高。

   2)@Transactional注解可读性高,内容分散不利于统一的管理和维护。

原文地址:https://www.cnblogs.com/hww123/p/5994390.html