[英]NHibernate concurrent update issue
I'm currently testing concurrent update situations for my c#/NHibernate application. 我目前正在为c#/ NHibernate应用程序测试并发更新情况。 In the hibernate-configuration
command_timeout
is set 1 second for testing purposes. 在hibernate-configuration中,将
command_timeout
设置为1秒以进行测试。 I use the hibernate version
in the mapping file. 我在映射文件中使用了休眠
version
。
Here is the code for testing: 这是测试代码:
namespace Test
{
class Program
{
static void Main(string[] args)
{
MyHibernateConnector hc = new MyHibernateConnector(); // 1 usage see below; also provides some other hibernate related methods
MyHibernateConfig myhibconfig = new MyHibernateConfig(); // reads and holds hibernate configuration
hc.setHibernateConfig(myhibconfig);
ISession session = hc.getSessionAndStartTransaction();
// getSessionAndStartTransaction() does the following:
// - on first call: reads the hibernate configuration and builds the SessionFactory
// - gets the session as follows:
// ISession session;
// if (CurrentSessionContext.HasBind(sf))
// {
// session = sf.GetCurrentSession();
// }
// else
// {
// session = sf.OpenSession();
// CurrentSessionContext.Bind(session);
// }
// - and does session.BeginTransaction();
MyClass obj;
IQuery q = session.CreateQuery("select mc from MyClass as mc where mc.ID = ?");
q.SetInt64(0, 60);
l = q.List<MyClass>();
if (l.Count > 0)
obj = l[0];
session.Transaction.Rollback();
// now update obj in another application with autocommit off and do not commit or rollback
/* breakpont is set here */ session = hc.getSessionAndStartTransaction();
try
{
session.Lock(obj, LockMode.Upgrade);
} catch (Exception e)
{
try
{
session.Transaction.Rollback();
}
catch (Exception e2)
{
Type t = e2.GetType();
}
}
// ...
}
}
}
On session.Lock(obj, LockMode.Upgrade)
an exception ( GenericADOException
) is thrown as expected with message: 在
session.Lock(obj, LockMode.Upgrade)
,异常( GenericADOException
)被抛出,并带有以下消息:
could not lock: … for update
If I now catch this exception and try to do an ISession.Transaction.Rollback()
a TransactionException
is thrown. 如果现在捕获此异常并尝试执行
ISession.Transaction.Rollback()
则会引发TransactionException
。
I would have expected that a rollback is the appropriate action to resolve concurrent update situations. 我希望回滚是解决并发更新情况的适当措施。 Is this not so ?
不是吗? And what would be the appropriate action ?
适当的行动是什么? What is the state of the transaction after the TransactionException ?
TransactionException之后事务的状态是什么?
I use NHibernate version 5.1.0.0 and MySql.Data version 6.10.7.0. 我使用NHibernate 5.1.0.0版和MySql.Data 6.10.7.0版。 Hibernate property
dialect
is NHibernate.Dialect.MySQL55InnoDBDialect
. Hibernate属性
dialect
是NHibernate.Dialect.MySQL55InnoDBDialect
。
After some more experimenting I think I found a solution - or should I better say a workaround: The ISession.Connection
is closed after timeout occured on session.Lock(obj, LockMode.Upgrade)
, so open it again before the rollback: 经过更多的试验后,我认为我找到了一个解决方案-还是我应该说一个解决方法:
ISession.Connection
在session.Lock(obj, LockMode.Upgrade)
发生超时后关闭,因此在回滚之前再次将其打开:
if (session.Connection.State.Equals(ConnectionState.Closed)) // <- !!!
session.Connection.Open();
session.Transaction.Rollback();
This works and I could do further transactions with the same session. 这行得通,我可以在同一会话中进行进一步的事务。
Why the connection is closed in the first place remains a mystery to me! 为什么首先关闭连接对我来说仍然是个谜!
And I wonder if this behaviour is common to other (all?) underlying DBMS and/or drivers. 而且我想知道这种行为是否对其他(所有?)底层DBMS和/或驱动程序通用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.