首先让我描述我面临的问题。
我们正在后端使用Jersey和MySQL开发一个Web服务。用户可以通过Restful API查看或编辑数据很简单,该服务将从MySQL数据库加载/保存数据。
我在MySQL服务器上创建了几个存储过程,如SelectAnswer和UpdateAnswer。在程序中,我们使用标准的JDBC和MySQL连接器连接到数据库。
首先,我为每个连接创建了存储过程。就像程序每次启动与数据库的新连接一样,它会创建一堆存储过程。
public enum JDBCDataSource {
INSTANCE;
private BasicDataSource dataSource = new BasicDataSource();
private Connection conn;
private CallableStatement answerUpsert;
private JDBCDataSource(){
initConnection();
try{
conn = dataSource.getConnection();
answerUpsert = prepareSP(answerUpsert,"{call upsert_answer(?, ?, ?)}");
} catch (SQLException e) {
e.printStackTrace();
}
}
程序每次调用都会重用存储过程:
private void executeUpsert(String app, String id, String content)
throws SQLException{
try {
CallableStatement callableStatement = JDBCDataSource.INSTANCE.getUpsert();
callableStatement.setString(1,app);
callableStatement.setInt(2,Integer.valueOf(id));
callableStatement.setString(3,content);
callableStatement.execute();
} catch (NumberFormatException e) {
e.printStackTrace();
} finally {
callableStatement.clearParameters();
}
}
因此每次调用该过程时,该函数都会设置自己的参数,并执行SP,最后清除参数。
但它不是线程安全的,如果用户发布了两个请求,一个请求尝试设置参数,另一个请求清除参数,则会导致异常。
因此,对于MySQL中的存储过程,我应该为每个事务或每个连接创建它以保持线程安全吗?也许我对SP和MySQL的理解不正确,或者可能是设计问题。请分享您的问题。