Transactional不会回滚@Hibernate

时间:2014-08-05 14:47:22

标签: java spring hibernate

我正在尝试为我的spring项目添加一个回滚机制,我已经按照一些教程解决了为什么回滚在以下代码中不会发生的问题:

@Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = TransactionException.class)
    public boolean changeSquad(ArrayList<Integer> playerIdList, String email) {
        boolean squadChanged = false;

        // Obtain the current list of players from the persistent storage
        TypedQuery<Player> playersQuery = emgr.createNamedQuery("Player.getUsersPlayers", Player.class);
        playersQuery.setParameter("email", email);



        List<Player> currentPlayerList = playersQuery.getResultList();

        // Make a copy of the list obtained as method parameter
        ArrayList<Integer> playerIdListCopy = new ArrayList<Integer>(playerIdList);

        // Make a copy of the list obtained from persistent storage
        ArrayList<Player> currentPlayerListCopy = new ArrayList<Player>(currentPlayerList);
        System.out.println("current player list copy = " + currentPlayerListCopy);



        // Iterate through each player from the currentPlayerList
        for (int i = 0; i < currentPlayerListCopy.size(); i++) {
            // On each iteration check if the playerIdList contains currently iterated 
            // Player's id, if so then eliminate it from both lists
            int playerId = currentPlayerListCopy.get(i).getPlayer_id();

            if (playerIdListCopy.contains(playerId)) {
                currentPlayerListCopy.remove(i);
                playerIdListCopy.remove(playerIdListCopy.indexOf(playerId));
                i--;
            }

        }
        // IF copy of current player list AND playerId list is empty, proceed
        if (currentPlayerListCopy.isEmpty() && playerIdListCopy.isEmpty()) {
            System.out.println("currentPlayerListCopy && playerIdListCopy = empty");

            // Make the squad changes

            for (int j = 0; j < currentPlayerList.size(); j++) {
                Player tempPlayer = currentPlayerList.get(j);
                int tempPlayerId = tempPlayer.getPlayer_id();

                // LOOP for all players from the client side list
                for (int n = 0; n < playerIdList.size(); n++) {
                    if (playerIdList.get(n) == tempPlayerId) {
                        ......
                    } 
                } // END loop for all players from the client side list 

                emgr.persist(tempPlayer);
                if (j == 13) {
                    System.out.println("j13, throwing exception");
                    try {
                        throw new TransactionException("sh.t happens");
                    } catch (Exception e) {
                        System.out.println("thrown and catched");

                        e.printStackTrace();
                    }
                }
            } // END loop for the player from the server side list
        } else {
            System.out.println("Seems like somebody messed up with the values.");
        }
        return squadChanged;
    }

抛出TransactionException后,除了回滚机制之外我会工作,但是它没有并且实体是持久的。

以下是persistence.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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">

    <!-- CREATES DATA SOURCE -->
    <!-- <bean class="java.net.URI" id="dbUrl">
        <constructor-arg value="#{systemEnvironment['DATABASE_URL']}" />
    </bean> -->

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="url"
            value="#{ 'jdbc:postgresql://' + 'localhost' + ':' + '5432' + '/handball' }" />
        <property name="username" value="'#{ 'postgres' }" />
        <property name="password" value="#{ '........' }" />
    </bean>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="emf">
        <!-- Entities location -->
        <property name="packagesToScan" value="af.handball.entity"></property>
        <property name="dataSource" ref="dataSource" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
            </props>
        </property>

         <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
        </property>  

    </bean>
</beans>

我很感激任何有关我可能出错的地方的信息,谢谢!

1 个答案:

答案 0 :(得分:3)

不要在事务方法中捕获异常。事务功能由包装服务对象的代理实现。例外必须到达代理,以便代理知道它需要回滚。如果您在服务方法中捕获异常,那么代理不知道该事务应该失败。

删除异常周围的try-catch块并抛出异常,您应该看到事务被回滚。