使用 ORMLite 在 RESTful 网络服务中进行交易

Transaction in RESTful web service with ORMLite

我正在使用 ORMLite 框架作为 ORM 创建 RESTful Web 服务。 重要的是我的一些服务是一个事务 - 如果发生任何异常,数据库应该回滚。

这是我创建的方法之一:

@POST
@CONSUMES(MediaType.APPLICATION_JSON)
@PRODUCES(MediaType.APPLICATION_JSON)
public JSONResponeseLogin getJson(LoginRequest request) {

    /* Extract data from request */

    openDBConnection();
    try {
        TransactionManager.callInTransaction(conn, () -> {
            /* Validate user input and store data to database */
        });
    } catch (InvalidDataInRequestException ex) {
        meta.addError(new ServiceError(errorCode));
        logger.info("Error code: "+ errorCode + " " + ServiceErrorCode.textFromErrorCode(errorCode));
        logger.info("Request: " + request.toString());
        logger.catching(ex);
    } catch (Exception e) {
        meta.addError(new ServiceError(errorCode));
        logger.info("Error code: "+ errorCode + " " + ServiceErrorCode.textFromErrorCode(errorCode));
        logger.info("Request: " + request.toString());
        logger.catching(ex);
    } finally {
        closeDBConnection();
    }

    response.setMetaData(meta);
    return response;
}

我有几个问题:

  1. 我是否使用了错误的工具来完成这项工作?我希望我的整个方法是一个事务,但我觉得 ORMLite 的 TransactionManager 不是为此而设计的。

  2. 事务中发生的每个异常都被包装到 SQLException 中(由 TransactionManager)。我无法区分和/或处理不同类型的异常。他们都陷入了异常块。我应该如何处理?

编辑: 我找到了一个可能的解决方法。

我可以使用单个连接实例(在整个 REST 方法的生命周期内从 ConnectionSource.getReadWriteConnection()) 获得。 我可以在所述连接上将自动提交设置为 false,并在抛出异常时手动回滚。

问题是我的 DAO 对象正在使用 JdbcPooledConnectionSource 进行初始化。

我想到的唯一问题是在服务器上这样做是安全的,每秒将收到约 10-20 个请求 - 必须有一个原因 DAO 正在接受整个池?

亲切的问候。

Am I using wrong tool for this job? I would like my whole method be one transaction, but I have a feeling that TransactionManager from ORMLite is not made for that.

不,是的。在您的 "possible workaround" 部分,这正是 TransactionManager 所做的:

  • 获取单个连接。
  • 停止自动提交。
  • 开始交易。
  • 做数据库工作。
  • 停止并提交事务。
  • 恢复自动提交。

Every exception which occurs in transaction is wrapped into SQLException (by TransactionManager).

没错。 TransactionManager 需要捕获异常,以便它可以回滚事务,但我不想从方法中抛出 Exception

您可以捕获 SQLException,然后手动检查 e.getCause() 输出。有点笨拙,但如果您想查看例外情况,则很有必要。

Is this safe to do on server which will get ~10-20 requests per second - there must be a reason DAO are accepting whole pool?

我不是 100% 确定你所说的安全是什么意思。我假设 Android 可以同时处理 10-20 个打开的数据库连接。这对 Android/Sqlite 来说更像是一个问题,然后是 ORMLite。这当然假设您的数据库作业完成所需的时间不到一秒。