由DateFormat引起的執行緒安全問題
阿新 • • 發佈:2018-12-19
有一次在測試環境中有個插入重複主鍵的問題,程式碼如下
@Transactional public void lending(OrderExtend order) { Date date = DateUtil.getCountyTime(); ................................... // 更新限額金額 String nowDate = DateUtil.timeToString(date, DateUtil.DATE_FORMAT_23);OrderLimit limit = orderLimitMapper.selectLimitByDate(nowDate, order.getAppPackage()); if (limit == null) {// SystemOption record = new SystemOption(); record.setOptionGroup("dailyorderlimit"); record.setOptionKey(order.getAppPackage()); List<SystemOption> list = systemOptionMapper.selectBySelective(record); limit = new OrderLimit(); limit.setAppName(order.getAppName()); limit.setAppPackage(order.getAppPackage()); limit.setLimitTime(date); limit.setApplyNumber(1); limit.setApplyAmount(order.getLendingAmount()); limit.setUpdateTime(date); limit.setMaxNumber(Integer.valueOf(list.get(0).getOptionValue())); orderLimitMapper.insertSelective(limit); } else { limit.setLimitTime(date); limit.setUpdateTime(date); limit.setApplyAmount(order.getLendingAmount()); orderLimitMapper.updateOrderLimitAmount(limit); } } public class DateUtil {
public static SimpleDateFormat DATE_FORMAT_23 = new SimpleDateFormat("yyyy-MM-dd");
public static String timeToString(Date d, DateFormat dateFormat) { if (d == null) { return null; } return dateFormat.format(d); } }
原因是orderLimitMapper.selectLimitByDate找不到值,結果插入導致重複的唯一鍵。然後分析居然是sql裡傳入的時間不對,傳入的時間是個莫名奇妙的日期,但這個時間是在方法內定義的一個區域性變數啊,應該不是執行緒安全啊。結果我想錯了,因為DATE_FORMAT_23是一個靜態變數,在方法區的變數照樣是在堆裡的,同樣會遇到執行緒安全的問題。網上一查果然SimpleDateFormat不是執行緒安全的