Spring常见的造成数据库连接泄露的写法

本文讲述了在Java编程中如何正确使用finally块来确保数据库连接和SQLSession的关闭,以及在try-catch-finally结构中处理事务的规则,包括PROPAGATION_REQUIRES_NEW策略和提交/回滚的时机判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 需要finally close
    Connection con = DataSourceUtils.getConnection(jdbcTemplate.getJdbcTemplate().getDataSource());
  2. 需要要finally close
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
  3. 需要commit或者rollback,如果finally没有处理事务不能提前return
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    TransactionStatus transaction = transactionManager.getTransaction(def);

如果需要手动处理事务,参考如下模板写法


TransactionStatus transaction = null;
try{
	DefaultTransactionDefinition def = new DefaultTransactionDefinition();
	// 可以设置一个当前事务的名称
    def.setName("xxxActionTrans");
    // 设置事务传播特性
	def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);	
	// 假如有提前返回,finally会处理提交
	if(xxx = true){
		return xxx;
	}
    xxxService.crudSQL()
    // crud 后尽快提交
	transactionManager.commit(transaction);
	// 假如存在异常
	throw new RuntimeException("e");
}catch(Exception e){
    transactionManager.rollback(transaction);
}
finally{
	// finally提交要判断事务已完成,不能重复提交和回滚
	if(!transaction.isCompleted()){
		transactionManager.commit(transaction);
	}
}

<think>好的,用户让我介绍一下Java开发中的常见注意事项,特别提到了“禁止在循环中查询数据库”。首先,我需要回忆一下常见Java开发中的陷阱和最佳实践。用户可能是一个刚入门的开发者,或者有一定经验但想优化代码的人。他们的真实需求可能是希望提高代码效率,避免常见错误,从而写出更高质量的Java应用。 首先,“禁止在循环中查询数据库”这个点,我应该解释为什么这样做不好,比如性能问题,多次连接数据库导致延迟增加,还可能引发资源耗尽。然后,给出解决方案,比如批量查询或者使用JOIN语句。 接下来,我需要扩展其他常见的注意事项。比如,资源未关闭会导致内存泄漏,应该用try-with-resources。还有字符串拼接用StringBuilder代替String,避免不必要的对象创建。集合初始化时指定容量,防止频繁扩容。异常处理要合理,不要捕获异常后不做处理。另外,使用equals方法时注意空指针,可以用Objects.equals或者Optional。多线程环境下要注意线程安全,比如ConcurrentHashMap的使用。避免创建过多不必要的对象,尤其是循环内部。BigDecimal用于精确计算,而不要用double。最后,使用日志框架而不是System.out,并且合理选择日志级别。 需要确保每个点都简明扼要,解释问题原因和解决方案。结构要清晰,分点列出,方便用户阅读。同时,要使用中文,避免专业术语过多,必要时举例说明。检查是否有遗漏的重要注意事项,比如NPE处理、代码规范等。最后,提醒用户这些是常见问题,实际开发中需结合具体情况处理。</think>以下是Java开发中常见的10个关键注意事项及解决方案(含具体案例): 1. **循环中禁止单条查询数据库** - 问题:100次循环查询产生100次数据库IO - 优化:`SELECT * FROM users WHERE id IN (1,2,3...)` - 工具:MyBatis的`<foreach>`标签实现批量查询 2. **资源必须关闭** ```java // 错误示范 FileInputStream fis = new FileInputStream("file.txt"); // 正确做法(JDK7+) try (FileInputStream fis = new FileInputStream("file.txt"); BufferedInputStream bis = new BufferedInputStream(fis)) { // 使用资源 } ``` 3. **字符串拼接优化** ```java // 低效方式(产生多个中间对象) String result = ""; for (int i=0; i<100; i++) { result += i; } // 高效方式 StringBuilder sb = new StringBuilder(200); // 预分配容量 for (int i=0; i<100; i++) { sb.append(i); } ``` 4. **集合初始化指定容量** ```java // 默认初始容量10,扩容消耗性能 List<User> users = new ArrayList<>(1000); // 明确预计容量 Map<String, User> map = new HashMap<>(1024); // 2的n次方最优 ``` 5. **异常处理规范** ```java // 错误做法 try { // code } catch (Exception e) { // 空catch块 } // 正确处理 try { // 业务代码 } catch (SpecificException e) { log.error("上下文信息", e); throw new BusinessException("友好提示"); } ``` 6. **NPE防御** ```java // 危险操作 user.getAddress().getCity().length(); // 安全方式 Optional.ofNullable(user) .map(User::getAddress) .map(Address::getCity) .orElse("默认城市"); ``` 7. **线程安全实践** ```java // 不安全写法 HashMap<String, Integer> map = new HashMap<>(); // 并发场景安全方案 ConcurrentHashMap<String, Integer> safeMap = new ConcurrentHashMap<>(); ``` 8. **避免过度自动装箱** ```java // 低效写法(触发Integer.valueOf) Integer sum = 0; for (int i=0; i<10000; i++) { sum += i; // 发生自动装箱 } // 优化方案 int sum = 0; // 使用基本类型 for (int i=0; i<10000; i++) { sum += i; } ``` 9. **精确计算使用BigDecimal** ```java // 错误方式 double d1 = 0.1; double d2 = 0.2; System.out.println(d1 + d2); // 输出0.30000000000000004 // 正确做法 BigDecimal b1 = new BigDecimal("0.1"); BigDecimal b2 = new BigDecimal("0.2"); System.out.println(b1.add(b2)); // 精确输出0.3 ``` 10. **日志规范** ```java // 不良实践 System.out.println("用户登录:" + user); // 标准做法 private static final Logger logger = LoggerFactory.getLogger(MyClass.class); if (logger.isDebugEnabled()) { logger.debug("用户登录成功,ID:{}", userId); // 使用占位符 } ``` **其他重要注意事项**: - 使用LongAdder替代AtomicLong应对高并发计数 - 避免在finally块中使用return语句 - 对外API必须进行参数校验(使用Apache Commons Validate或Spring Validation) - 日期处理统一使用Java8+的java.time包 - 敏感数据要脱敏(手机号、身份证号等) 建议结合SonarLint、SpotBugs等代码检测工具,在编码阶段及时发现问题。对于性能关键代码,应使用JMH进行基准测试验证优化效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值