提问人:Lia Lucindia 提问时间:11/11/2023 最后编辑:Lia Lucindia 更新时间:11/12/2023 访问量:49
用于 Connection.Query 的 Trans.commit
Trans.commit for Connection.Query
问:
我在下面有一个函数,它将通过存储过程将值插入到SQL DB中。我正在尝试实现trans.commit以使其更好,但是使用sp_insertTransaction2的存储过程在第一次插入时一直遇到错误:
当分配给命令的连接位于挂起的本地事务中时,ExecuteReader 要求命令具有事务。命令的 Transaction 属性尚未初始化
我在网上看到了很多教程,但是使用SQLCommand来初始化trans而不是使用连接。像我的代码一样查询。需要帮助来解决问题。
public bool insertTransactions(string receiver, string deliverer, string module, DateTime date, bool isChkout, int timeLapse, List<Lot> Lots)
{
using (var connection = new SqlConnection(ConnString))
{
connection.Open();
var trans = connection.BeginTransaction();
try
{
var data = connection.Query<TransactionsModel>("[sp_insertTransaction2]",
new
{
receiver,
deliverer,
module,
date,
isChkout,
timeLapse
},
commandTimeout: 120, commandType: CommandType.StoredProcedure);
**trans.Commit();**
foreach (var lot in Lots)
{
var data2 = connection.Query<TransactionsModel>("[sp_insertLot]",
new
{
lot.LotVPO,
lot.Bin,
lot.Location,
lot.Qty,
},
commandTimeout: 120, commandType: CommandType.StoredProcedure);
trans.Commit();
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("insertTransactions API error : " + ex.ToString());
trans.Rollback();
return false;
}
}
答:
1赞
Nick Vidalis
11/11/2023
#1
您正确地开始了交易,但您需要在每个 .有一个 IDbTransaction 方法参数。connection.BeginTransaction();
trans
Query<>()
此外,您不能提交两次事务。如果确实需要,您需要开始一个新的查询,但通常您在一个事务中完成所有查询并在最后提交。
评论
0赞
Lia Lucindia
11/11/2023
您是否有关于如何将事务 var trans 输入到 Query<>() 的示例?我在网上搜索了 IDbTransaction,但没有使用 Query<>() 代码大小写。
0赞
Nick Vidalis
11/11/2023
@LiaLucindia 首先,我假设您正在查看代码来使用 Dapper。例如,尝试在方法参数的末尾添加。您的 IDE(如果您使用的是 IDE)应该会为您提供帮助。, transaction: trans
0赞
Lia Lucindia
11/11/2023
这行得通。我只需要在commandTimeout:120之前指定trans,它就可以工作了。} trans, commandTimeout: 120...感谢您的帮助!
0赞
Alander
11/12/2023
我不同意这个答案,如果代码有效并不意味着它是交易的正确用法
0赞
Alander
11/12/2023
#2
这是因为你有多个 ,其中一个在 for 循环中。commit
事务意味着一切都成功完成,或者某些事情失败并触发了回滚。
如果你的目的是保存交易记录及其批号,那么你只能提交一次,否则将导致错误
dapper 提供了一个更好的类,如果代码未执行,该类将自动回滚TransactionScope
scope.Complete()
此外,用于读取行、插入/更新/删除 use 和 use 语句,用于连接和 transactionscope,因此它将自动关闭Query
Execute
using
public bool insertTransactions(string receiver, string deliverer, string module, DateTime date, bool isChkout, int timeLapse, List<Lot> Lots)
{
try
{
using (var connection = new SqlConnection(ConnString))
{
connection.Open();
using (var scope = new TransactionScope()) // use scope instead, its better
{ //use Execute when you insert/update/delete, Query is only for read
var data = connection.Execute<TransactionsModel>("[sp_insertTransaction2]",
new {
receiver,
deliverer,
module,
date,
isChkout,
timeLapse
}, commandTimeout: 120, commandType: CommandType.StoredProcedure);
foreach (var lot in Lots)
{
//use Execute when you insert/update/delete, Query is only for read
var data2 = connection.Execute<TransactionsModel>("[sp_insertLot]",
new
{
lot.LotVPO,
lot.Bin,
lot.Location,
lot.Qty,
}, commandTimeout: 120, commandType: CommandType.StoredProcedure);
}
scope.Complete(); //Or it will automatically rollback, call it only once!
}
}
}
catch (Exception ex)
{
Console.WriteLine("insertTransactions API error : " + ex.ToString());
trans.Rollback();
return false;
}
}
评论
Execute
Query
SqlBulkCopy