@Transactional事务管理下独立出一个事务对数据库进行操作,防止事务回滚了不想要回滚的更改
情景:
由于现在做的项目给前端的不正常提示都是通过抛出异常来返回的,抛出异常后会在拦截器中处理异常并将前端能看懂的提示返回给前端。
最近有个需求是登录错误将数据库的连续登录错误次数加1,成功错误次数清零,那么在同一事务下正常操作数据库进行加1,那么在登录错误后抛出异常“登录错误”,事务会回滚,导致加1的操作没有更新到数据库。
开始考虑利用多线程来操作,但是在操作较多的情况下数据容易错乱,所以想到“连续登录错误次数加1”这个更新操作利用原生jdbc进行数据库操作,然后手动控制jdbc的事务。
/**
* 更新连续登录错误次数
* 因为在事务里面,密码不正确会抛异常,所以如果使用普通的修改事务会回滚
* 这里采用原生jdbc保存的方式,手动提交
* @param userNo
* @return
*/
@Override
public int updateErrNum(String userNo){
DataSource dataSource = jdbcTemplate.getDataSource();
Connection connection = DataSourceUtils.getConnection(dataSource);
int result = 0;
try {
connection.setAutoCommit(false);//设置不自动提交
PreparedStatement stat = null;
String sql = "update xxxxxxxxxxxxx";
stat = connection.prepareStatement(sql);
stat.setString(1, userNo);
result = stat.executeUpdate();
connection.commit();//手动提交
connection.setAutoCommit(true);//还原
} catch (Exception e) {
e.printStackTrace();
try {//事务回滚
connection.rollback();
connection.setAutoCommit(true);
connection.close();
} catch (SQLException e1) {
throw new ServiceException(e1.getMessage());
}
throw new ServiceException(e.getMessage());
}
return result;
}
这里连接池会自己回收connection,如果不自动回收的就自己关闭或者其他操作吧。