无状态会话EJB 3.0中的事务回滚

时间:2011-02-03 07:47:36

标签: java transactions ejb-3.0 rollback

我有3.0规范的无状态会话EJB。

/*Remote Interface*/

package com.nseit.ncfm2.data.ejb;
import java.sql.SQLException;
import java.util.Collection;

import javax.ejb.Remote;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.naming.NamingException;

import com.nseit.ncfm2.security.Audit;

@Remote
public interface ProductionDataChangesRequestsRemote {

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public boolean shiftCandidateDetails(String sourceNcfmId,
            String destinationNcfmId, Collection<String> specialCasesList, String shiftingRemarks, String user, Audit updtAudit) throws NamingException, SQLException;
}


/*Bean Class*/

package com.nseit.ncfm2.data.ejb;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.naming.NamingException;

import com.nseit.ncfm2.security.Audit;
import com.nseit.ncfm2.util.server.lookup.LookUpServerResources;
import java.sql.*;
import java.util.*;

/**
 * Session Bean implementation class ProductionDataChangesRequestsBean
 */
@Stateless(name = "ProductionDataChangesRequestsBean", mappedName = "ProductionDataChangesRequestsEJB")
@Remote(ProductionDataChangesRequestsRemote.class)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class ProductionDataChangesRequestsBean implements
        ProductionDataChangesRequestsRemote {

/**
 * Default constructor.
 */
public ProductionDataChangesRequestsBean() {
    // TODO Auto-generated constructor stub
}

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public boolean shiftCandidateDetails(String sourceNcfmId,
        String destinationNcfmId, Collection<String> specialCasesList,
        String shiftingRemarks, String user, Audit updtAudit)
        throws NamingException, SQLException {
    // TODO Auto-generated method stub
    Connection conn = null;
    PreparedStatement pstmt = null;

    int updtCnt = 0;

    boolean areDetailsShifted = false;

    try {
        ..............
        ..............
        ..............

        /* Start: update table-1 */
        ..............
        ..............
        ..............

        updtCnt = pstmt.executeUpdate();
        ..............
        ..............
        ..............

        /* End: update table-1 */


        /* Start: update table-2 */
        ..............
        ..............
        ..............

        updtCnt = pstmt.executeUpdate();
        ..............
        ..............
        ..............

        /* End: update table-2 */

        areDetailsShifted = true;

    } /*catch (SQLException e) {
        // TODO Auto-generated catch block
        System.out
                .println("SQLException in ProductionDataChangesRequestsBean.shiftCandidateDetails(...) "
                        + e.getMessage());
        // e.printStackTrace();

        context.setRollbackOnly();

    } */finally {
        LookUpServerResources.closeStatement(pstmt);
        LookUpServerResources.closeConnection(conn);
    }

    return areDetailsShifted;
}

}

目前,如果第一个表更新成功并且第二个表更新发出异常,则不会发生回滚,即更新第一个表中的记录。

我希望在发生SQLException时回滚事务(或者就此而言,如果发生任何运行时异常)。

我尝试了两种方法:

  1. 在catch块中使用context.setRollbackOnly()进行SQLException
  2. 抛出SQLException
  3. 在这两种情况下,交易都没有回滚。

    我怎样才能做到这一点:

    1. 不使用@ApplicationException批注(因为我没有任何应用程序异常)
    2. 不捕获SQLException然后调用context.setRollbackOnly()
    3. 或者标准方式是什么?

3 个答案:

答案 0 :(得分:3)

您必须抛出RuntimeException

答案 1 :(得分:1)

标准方法是使用底层 JPA 进行持久化,而不是使用JDBC。 JPA 提供了一个标准的OR映射解决方案,它很好地集成到符合EJB 3.x的容器中。

同样来自您的代码,它反映出您拥有TransactionManagementType.CONTAINER,但仍然手动管理交易。

  

在bean管理的事务中   划分,会话中的代码   或显式的消息驱动bean   标志着边界   交易。虽然有豆子   容器管理的事务需要   编码较少,它们有一个限制:   当一个方法正在执行时,它可以   与单一相关联   交易或根本没有交易。   如果此限制将进行编码   你的豆很难,你应该   考虑使用bean管理   交易。

答案 2 :(得分:-1)

看起来您在bean中使用JDBC API。我认为容器不管理那些JDBC事务。对于CMT,您必须在容器管理实体管理器上调用操作才能使回滚按预期工作。