zoukankan      html  css  js  c++  java
  • 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="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/context
               http://www.springframework.org/schema/context/spring-context-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">
        <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
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-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">
        <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的提交么?
    */

  • 相关阅读:
    连接AI与用户,京东云推出视音频通信技术方案
    我身边的高T,问了Java面试者这样的问题......
    解密协议层的攻击——HTTP请求走私
    产业实践推动科技创新,京东科技集团3篇论文入选ICASSP 2021
    2021年人工智能数据采集标注行业四大趋势预测;清华提出深度对齐聚类用于新意图发现
    京东科技集团21篇论文高票入选国际顶会AAAI 2021
    别困惑,不是你的错!90%的开发者把Clubhouse看成了Clickhouse
    京东App Swift 混编及组件化落地
    对话京东科技算法科学家吴友政:回望2020,NLP技术发展速度强劲
    关于京东技术,你想了解的都在这里丨征文活动获奖及优秀专栏推荐
  • 原文地址:https://www.cnblogs.com/flying607/p/3488403.html
Copyright © 2011-2022 走看看