• Spring整合Hibernate:2、使用Annotation方式进行声明式的事务管理


    1、加入DataSourceTransactionManager的命名空间

    修改applicationContext.xml文件,增加如下内容:


    2、初始化HibernateTransactionManager

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <?xml version="1.0" encoding="UTF-8"?>
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        <context:annotation-config />
        <context:component-scan base-package="com.fz.annotation" />
        <bean
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations" value="classpath:jdbc.properties" />
        </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>
        <!-- annotation方式管理hibernate的sessionFactory -->
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="packagesToScan">
                <list>
                    <value>com.fz.annotation.model</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
        </bean>
        <tx:annotation-driven transaction-manager="myTxManager"/>
        <bean id="myTxManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    </beans>

    这里需要配置一个HibernateTransactionManager的bean和<tx:annotation-driven transaction-manager="myTxManager"/>

    3、在Service层使用事务管理

    userServiceImpl.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package com.fz.annotation.service.impl;
     
    import javax.annotation.Resource;
     
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
     
    import com.fz.annotation.dao.UserDao;
    import com.fz.annotation.model.User;
    import com.fz.annotation.service.UserService;
     
    @Service("userService")
    public class UserServiceImpl implements UserService{
        private UserDao userDao;
         
        @Transactional
        public void userAdd(User user) {
            userDao.userAdd(user);
        }
         
        public UserDao getUserDao() {
            return userDao;
        }
        @Resource(name="userDao")
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
         
    }

    注意:这里使用@Transactional注解来注明该方法需要使用到事务

    userDaoImpl.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    package com.fz.annotation.dao.impl;
     
    import javax.annotation.Resource;
     
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.springframework.stereotype.Repository;
     
    import com.fz.annotation.dao.UserDao;
    import com.fz.annotation.model.User;
     
     
    @Repository("userDao")
    public class UserDaoImpl implements UserDao{
        private SessionFactory sessionFactory;
        public void userAdd(User user) {
            Session session = sessionFactory.getCurrentSession();
            session.save(user);
        }
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }
        @Resource
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
    }

    4、测试

    测试正常情况,结果一切正常。数据库也插入了数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void getProperties(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext_aop.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        User user = new User();
        user.setId(4);
        user.setUsername("test1");
        userService.userAdd(user);
    }

    修改userDaoImpl.java,抛出一个异常。看看是否能回滚

    在userDaoImpl.java的userAdd方法中抛出一个异常

    1
    2
    3
    4
    5
    public void userAdd(User user) {
        Session session = sessionFactory.getCurrentSession();
        session.save(user);
        throw new RuntimeException("aa");
    }

    然后再次测试的时候,发现数据库中没有插入该条数据。依然是上一次的数据

    5、事务的传播特性Propagation

    所谓传播特性:也就是Transaction的产生过程,以及事务来了后怎么管理这个事务。

    @Transactional注解有个属性:Propagation,Propagation是一个枚举类型,默认是REQUIRED,枚举值如下:

    REQUIRED(默认,最常用,重要)

              Support a current transaction, create a new one if none exists. 

    如果此时执行了mothod1,而method1里面又调用了method2.假如method1里面已经有了Transaction,那么method2里面就不需要再创建新的Transaction了,method2会使用原来的这个Transaction。如果method1里面没有Transaction,则method2会新建一个Transaction

    例如:

    1
    2
    3
    4
    @Transactional(propagation=Propagation.REQUIRED)
    public void userAdd(User user) {
        userDao.userAdd(user);
    }

    如果别的service调用userAdd的时候已经有了Transaction,则此时不会创建新的Transaction。如果调用的时候没有Transaction。则这里会新建一个Transaction

    MANDATORY 

              Support a current transaction, throw an exception if none exists.

              必须得有Transaction,没有则抛异常。

    例如:如果把上面的REQUIRED改为MANDATORY,如果调用这个userAdd方法之前必须得有Transaction存在。否则则抛异常。

    1
    2
    3
    4
    @Transactional(propagation=Propagation.MANDATORY)
    public void userAdd(User user) {
        userDao.userAdd(user);
    }


    NESTED 

              Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.

              如果有一个Transaction(A)存在了,则暂停A。自己新建一个Transaction(B),等B执行完了,A才会继续执行。就是新建一个Transaction内嵌到原来的Transaction中。

    NEVER 

              Execute non-transactionally, throw an exception if a transaction exists.

              必须没有Transaction,如果有Transaction则抛异常。

    NOT_SUPPORTED 

              Execute non-transactionally, suspend the current transaction if one exists.

              必须不能有Transaction,如果有则挂起原来的Transaction,暂停原来的Transaction,执行当前方法内的Transaction后,原来的Transaction再继续。

    REQUIRES_NEW 

              Create a new transaction, suspend the current transaction if one exists.

              创建一个新Transaction,如果当前有Transaction。就将其挂起(暂停)

    SUPPORTS 

              Support a current transaction, execute non-transactionally if none exists.

              支持当前Transaction,如果当前有则有,当前没有则没有。












  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/meet/p/4762389.html
Copyright © 2020-2023  润新知