0
点赞
收藏
分享

微信扫一扫

Spring 声明式事务管理


声明事务可以省去手动添加事务以及异常处理的麻烦。



注解方式:


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

    xmlns:aop="​​​​http://www.springframework.org/schema/aop"​​​​

    ​xmlns:tx="​​​​​​​​​​

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

​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​

           ​​​​​​​​​​​
          
​​​​​​​​"​​​>

    <context:annotation-config />

    <context:component-scan base-package="com.bjsxt" />

    <!--

        <bean id="dataSource"

        class="org.apache.commons.dbcp.BasicDataSource"

        destroy-method="close">



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

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

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

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

        </bean>

    -->

    <bean

        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

        <property name="locations">

            <value>classpath:jdbc.properties</value>

        </property>

    </bean>

    <bean id="dataSource" destroy-method="close"

        class="org.apache.commons.dbcp.BasicDataSource">

        <property name="driverClassName"

            value="${jdbc.driverClassName}" />

        <property name="url" value="${jdbc.url}" />

        <property name="username" value="${jdbc.username}" />

        <property name="password" value="${jdbc.password}" />

    </bean>

    <bean id="sessionFactory"

        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

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

        <property name="annotatedClasses">

            <list>

                <value>com.bjsxt.model.User</value>

                <value>com.bjsxt.model.Log</value>

            </list>

        </property>

        <property name="hibernateProperties">

            <props>

                <prop key="hibernate.dialect">

                    org.hibernate.dialect.MySQLDialect

                </prop>

                <prop key="hibernate.show_sql">true</prop>

            </props>

        </property>

    </bean>

    <bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
   
    <tx:annotation-driven transaction-manager="txManager"/>



</beans>






package com.bjsxt.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.LogDAO;

import com.bjsxt.dao.UserDAO;

import com.bjsxt.model.Log;

import com.bjsxt.model.User;


@Component("userService")

public class UserService {


    private UserDAO userDAO;

    private LogDAO logDAO;


    public void init() {

        System.out.println("init");

    }


    public User getUser(int id) {

        return null;

    }


    @Transactional//加上之后相当于自动在其前后添加了事务和try。

    public void add(User user) {


            userDAO.save(user);

            Log log = new Log();

            log.setMsg("a user saved!");

            logDAO.save(log);


    }

    public UserDAO getUserDAO() {

        return userDAO;

    }


    @Resource(name="u")

    public void setUserDAO( UserDAO userDAO) {

        this.userDAO = userDAO;

    }



    public LogDAO getLogDAO() {

        return logDAO;

    }


    @Resource

    public void setLogDAO(LogDAO logDAO) {

        this.logDAO = logDAO;

    }

    public void destroy() {

        System.out.println("destroy");

    }

}



import javax.annotation.Resource;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.springframework.stereotype.Component;

import com.bjsxt.dao.LogDAO;

import com.bjsxt.model.Log;

@Component("logDAO")

public class LogDAOImpl implements LogDAO {

    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {

        return sessionFactory;

    }


    @Resource

    public void setSessionFactory(SessionFactory sessionFactory) {

        this.sessionFactory = sessionFactory;

    }

    public void save(Log log) {


        Session s = sessionFactory.getCurrentSession();

        s.save(log);

        //throw new RuntimeException("error!");

    }

}




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

    xmlns:aop="​​​​http://www.springframework.org/schema/aop"​​​​

    xmlns:tx="​​​​http://www.springframework.org/schema/tx"​​​​

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

​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​ ​​​​

           ​​

​​> ​​

    <context:annotation-config />

    <context:component-scan base-package="com.bjsxt" />

    <!--

        <bean id="dataSource"

        class="org.apache.commons.dbcp.BasicDataSource"

        destroy-method="close">



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

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

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

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

        </bean>

    -->

    <bean

        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

        <property name="locations">

            <value>classpath:jdbc.properties</value>

        </property>

    </bean>

    <bean id="dataSource" destroy-method="close"

        class="org.apache.commons.dbcp.BasicDataSource">

        <property name="driverClassName"

            value="${jdbc.driverClassName}" />

        <property name="url" value="${jdbc.url}" />

        <property name="username" value="${jdbc.username}" />

        <property name="password" value="${jdbc.password}" />

    </bean>

    <bean id="sessionFactory"

        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

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

        <!--

        <property name="annotatedClasses">

            <list>

                <value>com.bjsxt.model.User</value>

                <value>com.bjsxt.model.Log</value>

            </list>

        </property>

         -->

         <property name="packagesToScan">

            <list>

                <value>com.bjsxt.model</value>


            </list>

        </property>

        <property name="hibernateProperties">

            <props>

                <prop key="hibernate.dialect">

                    org.hibernate.dialect.MySQLDialect

                </prop>

                <prop key="hibernate.show_sql">true</prop>

            </props>

        </property>

    </bean>

    <bean id="txManager"

        class="org.springframework.orm.hibernate3.HibernateTransactionManager">

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

    </bean>

    <aop:config>

        <aop:pointcut id="bussinessService"

            expression="execution(public * com.bjsxt.service..*.*(..))" />

        <aop:advisor pointcut-ref="bussinessService"

            advice-ref="txAdvice" />

    </aop:config>

    <tx:advice id="txAdvice" transaction-manager="txManager">

        <tx:attributes>

            <tx:method name="getUser" read-only="true" />

            <tx:method name="add*" propagation="REQUIRED"/>

        </tx:attributes>

    </tx:advice>


</beans>






@Transactional(propagation=Propagation.REQUIRED) 和  @Transactional是一样?

ServiceA {  

/**  

* 事务属性配置为 PROPAGATION_REQUIRED 

*/ 

void methodA() { 

ServiceB.methodB(); 

}

ServiceB {  

/**  

* 事务属性配置为 PROPAGATION_REQUIRED 

*/ 

void methodB() { 



PROPAGATION_REQUIRED 

加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务

比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候,

ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA

的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。

这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚

/**

* 如果ServiceB.methodB出现异常,会影响到ServiceA.methodA的提交么?

*/


举报

相关推荐

0 条评论