使用 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;
}
我有几个问题:
我是否使用了错误的工具来完成这项工作?我希望我的整个方法是一个事务,但我觉得 ORMLite 的 TransactionManager 不是为此而设计的。
事务中发生的每个异常都被包装到 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。这当然假设您的数据库作业完成所需的时间不到一秒。
我正在使用 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;
}
我有几个问题:
我是否使用了错误的工具来完成这项工作?我希望我的整个方法是一个事务,但我觉得 ORMLite 的 TransactionManager 不是为此而设计的。
事务中发生的每个异常都被包装到 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。这当然假设您的数据库作业完成所需的时间不到一秒。