强制执行查询而不刷新/提交
您好,我正在使用asp.net web应用程序的事务处理每个请求(会话在视图中)模式。 我在应用程序中有几点要保存一个NHibernate管理实体,然后使用普通的SQL做更多的插入和更新。 这些插入/更新取决于NH保存实体将采用的ID。
问题是生成的id不存在于事务的范围中。 如果我强制刷新/提交该ID是持久的,但如果插入/更新失败,我必须回滚,但刷新/提交的实体不会。 目前,我正在为这些案例进行手动插入,但这是我想要更改的内容。 那么,有没有办法在Save()之后执行SQL语句(在已经打开的事务中),但不强制刷新/提交?
编辑:我添加了一个半伪代码的例子,我有4个错误的答案,所以我认为人们不明白(如何NHibernate的作品)在开始请求我发出
nhsession.BeginTransaction()
然后在某个时候我做
FooClass fc = new FooClass("value");
nhsession.Save(fc);
ITransaction trans = nhsession.Transaction;
SqlCommand sc = new SqlCommand("some insert/update query that depends on fc's id", (SqlConnection)nhsession.Connection);
sc.Parameters.Add("id", fc.Id); //NHibernate generates the id, note i'm using assigned/hi-lo so no round trip to the db takes place
transaction.Enlist(sc);
try {
sc.ExecuteNonQuery();
}
catch (SqlException ex){
transaction.RollBack();
nhsession.Close();
}
并且在请求结束时我发出一个CommitTransaction()
和nhsession.Close()
现在这完全没有办法: FooClass (fc)
没有被刷新/提交到数据库。 NH完成的Save()
操作已经达到了内存中的这一点。 这意味着nhibernate没有发出sql命令,这意味着之后我触发的SqlCommand (sc)
会因为该id不存在而失败。
如果我在Save()
和SqlCommand
之间执行flush / commit, FooClass(fc)
_cannot_be_rolled_back_并且这是一件坏事。 目前,为了这个工作,我使用SqlCommand
进行了vanila sql插入,并且我想改变它。 (为什么?因为我不想制作香草插页,所以他们容易因模式/模型更改而出错,并且我为此获得了OR / M)
怎么样? 我想通知NHibernate以某种方式执行SqlCommand
以对应于Save()
插入(地狱,它可以执行它收集的所有SqlCommand),但没有它提交或刷新!
目前,我还在搜索nhibernate在刷新/提交保存的对象时产生的准备好的sql语句。 也许我可以只取这个字符串,然后在我的SqlCommand中运行,这个SqlCommand被加入了Transaction。
也许我不明白,但你不能这样做...
using(var tx = session.BeginTransaction())
{
session.Save(entity);
session.Flush();
//perform non NH operations with entity.id
tx.Commit();
}//uncommitted transaction would be rolled back on dispose()
你不能使用嵌套事务或事务范围来支持它吗?
基本上你所要求的是在你使用它之前分配这个id,生成的id只在刷新修改时才分配,修改只在事务边界刷新,因此你不能创建一个内部事务范围来包装nh相关的持久性强制刷新和id生成,但仍允许外部事务失败并在存储过程失败时回滚所有工作。
我如何在NHibernate中嵌套事务? 有一些示例代码演示了使用范围的方法。
听起来就像你在交易过程中想要'读取'隔离级别。 这可以让你阅读'uncommited'但保存好的内容。 然而,我不能在NHibernate中足够流畅地提供任何有关如何在那里做的洞察。
我确信有人可以关注如何为NH做'dirty read'隔离级别。
链接地址: http://www.djcxy.com/p/23235.html