Tomcat7中使用JDBC连接池进行事务处理

时间:2015-06-22 12:07:19

标签: jsf jdbc transactions db2 connection-pooling

我正在开发一个JSF应用程序,它通过Tomcat 7配置使用JNDI连接池到DB2数据库。我在管理事务时遇到问题,更具体地说,当从共享连接的方法抛出异常时回滚。

以下代码建立连接并将其传递给所有其他被调用的方法。然后,仅在方法的finally块中关闭此连接。我的问题是,例如......如果在方法中的任何一点抛出异常,那么在此之前完成的任何工作都会被提交而不会回滚。我的印象是,当关闭finally块中的连接时,如果在此连接的生命周期内抛出任何异常,则无法提交,无论工作是否已提交或回滚,连接都将返回到池中

public boolean updateSubCountry(SubCountryDTO dto,
        List<FeatureAliasDTO> aliases, List<FeatureCodeDTO> codes)
        throws ReferenceDataException {
    boolean success = true;
    Connection c = null;
    try {
        c = fDao.getConnection();
        success = fDao.updateSubCountry(c, dto, TEMP_USERNAME) && success;
        success = updateAliases(c, aliases, dto.getOdi(), TEMP_USERNAME,
                dto.getSubCountryId()) && success;
        for (FeatureCodeDTO codeDto : codes) {
            success = updateFeatureCode(c, codeDto, dto.getSubCountryId())
                    && success;
        }
    } finally {
        closeConnection(c, DEFAULT_CONNECTION_ERROR_MSG);
    }
    return success;
}

我的JNDI配置如下(敏感信息已加星标):

<Resource name="jdbc/core" auth="Container" type="javax.sql.DataSource"
         url="****"
         driverClassName="com.ibm.db2.jcc.DB2Driver"
         username="****" password="****"
         maxActive="20" maxIdle="3" maxWait="10000"
         poolPreparedStatements="true"
         maxOpenPreparedStatements="100"
         validationQuery="SELECT 1 FROM SYSIBM.SYSDUMMY1" />

感谢任何帮助。

感谢。

更新

我试图实施@Tiny提出的建议。但是,当故意使updateFeatureCode()方法在数据库级别上抛出异常时,之前的任何工作仍然没有回滚?

@Transactional (rollbackFor={Exception.class, ReferenceDataException.class})
    public boolean updateSubCountry(SubCountryDTO dto,
            List<FeatureAliasDTO> aliases, List<FeatureCodeDTO> codes)
            throws ReferenceDataException {
        boolean success = true;
        Connection c = null;
        try {
            c = fDao.getConnection();
            success = fDao.updateSubCountry(c, dto, TEMP_USERNAME) && success;
            success = updateAliases(c, aliases, dto.getOdi(), TEMP_USERNAME,
                    dto.getSubCountryId()) && success;
            for (FeatureCodeDTO codeDto : codes) {
                success = updateFeatureCode(c, codeDto, dto.getSubCountryId())
                        && success;
            }
        } finally {
            closeConnection(c, DEFAULT_CONNECTION_ERROR_MSG);
        }
        return success;
    }

1 个答案:

答案 0 :(得分:-1)

IBM JDBC驱动程序在连接到DB2数据库时默认为autoCommit=true,这意味着在每个语句之后发出显式COMMIT。如果您希望自己控制事务,请根据需要禁用自动提交和提交或回滚。或者,正如@Tiny所建议的那样,使用事务管理器。