
离线 TA的专栏
- 打卡等级:即来则安
- 打卡总天数:25
- 打卡月天数:0
- 打卡总奖励:288
- 最近打卡:2025-03-18 10:18:58
|
1. 引言
在数据库操作中,处理重复数据插入是一个常见的需求。特别是在批量插入数据时,可能会遇到主键冲突或唯一键冲突(Duplicate entry)的情况。如何优雅地捕获这类异常并执行相应的业务逻辑,是提高代码健壮性的关键。
本文将以一个实际的Python MySQL数据库操作为例,分析如何优化异常处理逻辑,使得当出现Duplicate entry错误时,能够执行特定的业务方法(如更新记录状态)。同时,我们也会对比Java中的类似处理方式,帮助读者更好地理解不同语言下的异常处理机制。
2. 问题背景
2.1 原始代码分析
原始代码的功能是批量插入手机号数据到MySQL数据库,其核心逻辑如下: - def insert_into_mysql(phone_numbers, prefix, province, city):
- try:
- connection = get_db_connection()
- cursor = connection.cursor()
-
- data_to_insert = []
- for phone_number in phone_numbers:
- if len(phone_number) == 11:
- suffix = phone_number[-4:]
- data_to_insert.append((prefix, suffix, phone_number, province, city))
-
- cursor.executemany(INSERT_QUERY, data_to_insert)
- connection.commit()
- return True
-
- except Exception as e:
- print(f"插入数据失败: {e}")
- if connection:
- connection.rollback()
- return False
-
- finally:
- if cursor:
- cursor.close()
- if connection:
- connection.close()
复制代码 2.2 存在的问题
- 异常处理不够精细:仅打印错误信息并回滚,没有针对特定错误(如)进行特殊处理。
- 业务逻辑耦合度低:当数据重复时,可能需要执行额外操作(如更新记录状态),但原始代码没有提供这样的扩展点。
3. 优化方案
3.1 目标
- 捕获特定异常:当错误信息包含时,执行额外逻辑(如调用方法)。
- 保持代码健壮性:确保事务回滚和资源释放不受影响。
3.2 优化后的Python代码
- def insert_into_mysql(phone_numbers, prefix, province, city, url=None):
- connection = None
- cursor = None
- try:
- connection = get_db_connection()
- if not connection:
- print("数据库连接失败")
- return False
- cursor = connection.cursor()
- data_to_insert = []
-
- for phone_number in phone_numbers:
- if len(phone_number) == 11:
- suffix = phone_number[-4:]
- data_to_insert.append((prefix, suffix, phone_number, province, city))
- if not data_to_insert:
- print("警告: 没有有效的手机号可插入")
- return False
- cursor.executemany(INSERT_QUERY, data_to_insert)
- connection.commit()
- print(f"成功插入 {len(data_to_insert)} 条数据")
- return True
- except Exception as e:
- print(f"插入数据失败: {e}")
- if connection:
- connection.rollback()
-
- # 检查是否是唯一键冲突
- if "Duplicate entry" in str(e):
- if url: # 确保url有效
- update_is_deal(url, province, city) # 执行额外逻辑
-
- return False
-
- finally:
- if cursor:
- cursor.close()
- if connection:
- connection.close()
复制代码 3.3 关键优化点
- 精细化异常捕获:通过检查异常信息是否包含,判断是否为唯一键冲突。
- 支持额外参数:新增参数,确保方法可以正确执行。
- 事务安全:即使执行额外逻辑,仍然保证事务回滚和资源释放。
4. Java对比实现
在Java中,MySQL的 错误通常对应 - SQLIntegrityConstraintViolationException
复制代码,我们可以采用类似的优化策略。
4.1 Java版本优化代码
- import java.sql.*;
- import java.util.List;
- public class PhoneNumberDao {
- private static final String INSERT_QUERY =
- "INSERT INTO phone_numbers (prefix, suffix, phone_number, province, city) " +
- "VALUES (?, ?, ?, ?, ?)";
- public boolean insertIntoMysql(List<String> phoneNumbers, String prefix,
- String province, String city, String url) {
- Connection connection = null;
- PreparedStatement statement = null;
-
- try {
- connection = DatabaseUtil.getConnection(); // 获取数据库连接
- connection.setAutoCommit(false); // 开启事务
-
- statement = connection.prepareStatement(INSERT_QUERY);
-
- for (String phoneNumber : phoneNumbers) {
- if (phoneNumber.length() == 11) {
- String suffix = phoneNumber.substring(7); // 后4位
- statement.setString(1, prefix);
- statement.setString(2, suffix);
- statement.setString(3, phoneNumber);
- statement.setString(4, province);
- statement.setString(5, city);
- statement.addBatch(); // 加入批处理
- }
- }
-
- statement.executeBatch(); // 执行批处理
- connection.commit(); // 提交事务
- return true;
-
- } catch (SQLIntegrityConstraintViolationException e) {
- // 捕获唯一键冲突异常
- System.err.println("插入数据失败(唯一键冲突): " + e.getMessage());
- if (connection != null) {
- try {
- connection.rollback(); // 回滚事务
- } catch (SQLException ex) {
- ex.printStackTrace();
- }
- }
-
- if (url != null) {
- updateIsDeal(url, province, city); // 执行额外逻辑
- }
- return false;
-
- } catch (SQLException e) {
- System.err.println("插入数据失败: " + e.getMessage());
- if (connection != null) {
- try {
- connection.rollback();
- } catch (SQLException ex) {
- ex.printStackTrace();
- }
- }
- return false;
-
- } finally {
- // 关闭资源
- try {
- if (statement != null) statement.close();
- if (connection != null) connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- private void updateIsDeal(String url, String province, String city) {
- // 实现更新逻辑
- System.out.println("检测到重复数据,更新状态: " + url);
- }
- }
复制代码 4.2 Java优化点
- 精准捕获
- SQLIntegrityConstraintViolationException
复制代码 ,而不是笼统的。
- 批处理优化:使用和提高插入效率。
- 事务管理:显式控制和,确保数据一致性。
5. 总结与最佳实践
5.1 关键总结
优化点Python 实现Java 实现异常捕获检查 是否包含 捕获 - SQLIntegrityConstraintViolationException
复制代码事务管理 资源释放 块关闭连接 块关闭资源批处理优化 +
5.2 最佳实践
- 精细化异常处理:不要仅捕获,而应根据业务需求区分不同错误类型。
- 事务安全:确保异常发生时能正确回滚,避免脏数据。
- 资源释放:使用或(Java)确保数据库连接关闭。
- 日志记录:在异常处理时记录足够的信息,便于排查问题。
6. 扩展思考
- 是否应该先查询再插入?
- 如果数据量较大,先查询再插入可能影响性能,直接捕获更高效。
- 如何优化逻辑?
- 可以引入异步处理(如消息队列),避免影响主流程性能。
- 是否可以用或?
- 取决于业务需求,如果需要静默忽略重复数据,可以使用这些SQL语法。
7. 结语
通过本文的优化案例,我们学习了如何在Python和Java中精细化处理MySQL的 错误,并执行额外的业务逻辑。关键在于:
到此这篇关于MySQL处理重复数据插入的处理方案的文章就介绍到这了,更多相关MySQL重复数据插入处理内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:  进行删除处理。
4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
|