-
现在有如下的业务场景:
数据库里边只有id,time2个字段,数据库里边id是自增的。现在需要对id进行一次更新之后,再去进行查询,
以期获得最新的id,并返回给业务方。
public IDGenerateEntityDb execSql(final String time) throws Exception {
DaoWrapper wrapper = BaseDaoWrapperFactory.getDaoWrapper();
final String sql = "replace into tbl (time) values(" + time + ")";
IDGenerateEntityDb db = new IDGenerateEntityDb();
final Lock lock = new ReentrantLock();
lock.lock();
Long id = (Long) wrapper.execInsert(sql, new IPreparedStatementHandler() {
public Object exec(PreparedStatement paramPreparedStatement) throws SQLException {
int s = paramPreparedStatement.executeUpdate(sql);// 返回的是执行的条数
Long idLong = null;
try {
if (s == 1 || s == 2) { // 表明执行成功
ResultSet set = paramPreparedStatement.executeQuery(" SELECT * from tbl where time= " + time);
while (set.next()) {
idLong = set.getLong("id");
System.out.println(idLong);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return idLong;
}
});
db.setId(id);
return db;
}用这种方式的时候,拿到的结果就会有重复数据,但是将ReentrantLock改为Synchronized后拿到的结果就正常了,这是什么原因呢。是不是加锁的额方式不对呢?
关于多线程下Synchronized锁和ReentrantLock的问题
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
- july_apple 2016-07-16 06:18关注
finally代码块中执行lock.unlock(),此时释放了锁,但在释放锁之前,已经有返回值了。你将return idLong;放到lock.unlock();之后就可以了。
解决 无用评论 打赏 举报