1. 程式人生 > >由DateFormat引起的執行緒安全問題

由DateFormat引起的執行緒安全問題

有一次在測試環境中有個插入重複主鍵的問題,程式碼如下

@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不是執行緒安全的