SqlConnection是否有默认事务?C#执行多条删除SQL是否需显式声明事务
问题1:SqlConnection是否存在默认事务?
默认不存在跨多条SQL语句的全局默认事务,SqlConnection默认工作在自动提交模式下:每一条单独执行的SQL语句都会被作为独立事务处理,执行完成后自动提交变更,无法自动聚合多条SQL为一个原子操作。
问题2:如果其中一条查询返回错误会发生什么情况?
你当前的写法下,假设前N条DELETE语句执行成功,第N+1条执行出错(比如外键约束报错、字段不存在等):
- 已经执行成功的前N条DELETE的修改会被永久提交到数据库,不会自动回滚
- 后续未执行的SQL语句会终止执行
- 代码会抛出
SqlException异常
最终会出现数据不一致的问题:部分关联表的对应数据被删除,剩余表的关联数据保留,产生脏数据。
问题3:是否需要显式声明事务?
需要。你这种多表关联数据批量删除的场景,必须保证操作的原子性:要么所有表的对应数据全部删除成功,要么全部不删,避免出现数据不一致的问题。
另外你原代码使用字符串拼接SQL存在SQL注入风险,推荐改为参数化查询,配合显式事务的写法参考如下:
using (SqlConnection sqlCon = new SqlConnection(ler())) { sqlCon.Open(); // 开启显式事务 using (SqlTransaction transaction = sqlCon.BeginTransaction()) { try { // 参数化查询避免SQL注入 string query = @"DELETE FROM aux_evento WHERE id_pessoa = @Id; DELETE FROM aux_lista WHERE id_pessoa = @Id; DELETE FROM convite WHERE Id = @Id; DELETE FROM contacto WHERE Id = @Id; DELETE FROM ficha WHERE id_pessoa = @Id;"; SqlCommand sqlCmd = new SqlCommand(query, sqlCon, transaction); // 添加参数 sqlCmd.Parameters.AddWithValue("@Id", id); sqlCmd.ExecuteNonQuery(); // 所有语句执行成功,提交事务 transaction.Commit(); } catch (Exception ex) { // 任意语句出错,回滚所有修改 transaction.Rollback(); // 可按需处理异常,比如记录日志、向上抛出 throw; } } }
内容的提问来源于stack exchange,提问作者user2382627
相关产品推荐
相关产品推荐

