我想使用ormlite的事务,但是我没有使用ormlite添加的扩展方法OpenTransaction,我想使用IDbConnection.BeginTransaction,因为我没有在我希望管理事务的项目中引用ormlite。
所以我喜欢:
using (var dbTrans = db.BeginTransaction())
{
// do some work
dbTrans.Commit();
}
但这会引发以下异常:
System.InvalidOperationException: ExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
Result StackTrace:
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at StackExchange.Profiling.Data.ProfiledDbCommand.ExecuteNonQuery() in c:\TeamCity\buildAgent\work\1de24adb938b932d\StackExchange.Profiling\Data\ProfiledDbCommand.cs:line 277
at ServiceStack.OrmLite.OrmLiteCommand.ExecuteNonQuery()
at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.ExecuteSql(IDbCommand dbCmd, String sql)
at ServiceStack.OrmLite.WriteExpressionCommandExtensions.Update[T](IDbCommand dbCmd, T item, Expression`1 expression)
at ServiceStack.OrmLite.OrmLiteWriteExpressionsApi.<>c__DisplayClassd`1.<Update>b__c(IDbCommand dbCmd)
at ServiceStack.OrmLite.OrmLiteExecFilter.Exec[T](IDbConnection dbConn, Func`2 filter)
at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.Exec[T](IDbConnection dbConn, Func`2 filter)
at ServiceStack.OrmLite.OrmLiteWriteExpressionsApi.Update[T](IDbConnection dbConn, T item, Expression`1 where)
...
当我调试时,我注意到在事务开始后没有设置db对象的Transaction属性。我查看了源代码OrmLiteConnection.cs#L48,我无法看到是否曾将事务分配给OrmLiteConnection.Transaction。
这是需要在OrmLiteConnection.BeginTransaction中解决的问题,还是我使用BeginTransaction错了?
答案 0 :(得分:1)
在OrmLite中打开事务的API为db.OpenTransaction()
,获得assigned in the OrmLiteTransaction contructor并自动分配给在事务范围内创建的每个db命令。
如果您想使用ADO.NET的原生BeginTransaction()
API,您需要自己将其分配给ADO.NET IDbCommand
,即:
using (var db = OpenDbConnection())
using (var dbTrans = db.BeginTransaction())
using (var dbCmd = db.CreateCommand())
{
dbCmd.Transaction = dbTrans;
// do some work
dbTrans.Commit();
}