public static int executeCreateandReturnID(String SQL,String poolName) {
if (SQL == null || SQL.length() == 0) {
return 0;
}
int i = 0, nCreateId = 0;
Connection conn = DBService.getConn(poolName);
try {
// System.out.println(SQL);
Statement stmt = conn.createStatement();
i = stmt.executeUpdate(SQL);
if (i > 0) {
//Get IDENTITY id
ResultSet rs = stmt.executeQuery( "SELECT @@IDENTITY ");
if (rs.next()) {
nCreateId = rs.getInt(1);
}
rs.close();
}
stmt.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
DBService.closeConn(poolName,conn);
}
return nCreateId;
}
现在我程序偶尔会发生执行这段代码后,返回的ID值是0,而实际insert语句是执行成功的。代码如上,请各位老大帮忙看看,哪里出了问题?怀疑的重点是连接池中其他会话的并发引起的
怎么解决?最好能说明原因。
这个系统再我们这边测试的时候都没有问题,但是在用户那边用上去不久经常发现数据错乱,用户那边催的很急啊,请各位大侠相助啊。
问题解决立马送分
------解决方案--------------------
@@IDENTITY 用 SCOPE_IDENTITY() 替换试试。
------解决方案--------------------
stmt.executeUpdate(SQL);
既然是想返回值那么LZ的写法有点多余了
这样的写法就很好了,没有必要去判断更新所影响的行数,然后决定是否去取identity的值
把两句话放在一起执行可以保证返回的IDENTITY值绝对正确,
而且如果返回的IDENTITY值0那么肯定是执行失败了,程式中少做了很多无用功
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(SQL + ";SELECT @@IDENTITY ");
if (rs.next()) {
nCreateId = rs.getInt(1);
}
rs.close();
或者在传入SQL这个参数之前就在后面加上+ ";SELECT @@IDENTITY "
另外建议用SCOPE_IDENTITY()替代@@IDENTITY,因为@@IDENTITY是全局变量,而SCOPE_IDENTITY()的作用域只限于当前连接,虽然这样的替换不是必要,但是相信LZ应该很清楚使用全局变量和局部变量那个更好