Проблема одновременного обновления NHibernate - PullRequest
0 голосов
/ 29 ноября 2018

В настоящее время я тестирую параллельные ситуации обновления для моего приложения c # / NHibernate.В hibernate-конфигурации command_timeout устанавливается 1 секунда для целей тестирования.Я использую hibernate version в файле сопоставления.

Вот код для тестирования:

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();
                }
            }
            // ...
        }
    }
}

При session.Lock(obj, LockMode.Upgrade) исключение (GenericADOException) генерируется, как и ожидалось ссообщение:

could not lock: … for update

Если я сейчас поймаю это исключение и попытаюсь сделать ISession.Transaction.Rollback() a TransactionException, то выбрасывается.

Я бы ожидал, что откат является подходящим действием дляразрешить параллельные ситуации обновления.Это не так?И какие будут соответствующие действия?Каково состояние транзакции после TransactionException?

Я использую NHibernate версии 5.1.0.0 и MySql.Data версии 6.10.7.0.Свойство Hibernate dialect является NHibernate.Dialect.MySQL55InnoDBDialect.

1 Ответ

0 голосов
/ 03 декабря 2018

После еще нескольких экспериментов, я думаю, что я нашел решение - или лучше сказать обходной путь: ISession.Connection закрывается после истечения времени ожидания на session.Lock(obj, LockMode.Upgrade), поэтому откройте его снова перед откатом:

if (session.Connection.State.Equals(ConnectionState.Closed)) // <- !!!
    session.Connection.Open();
session.Transaction.Rollback();

Это работает, и я мог бы делать дополнительные транзакции с тем же сеансом.

Почему соединение закрыто, во-первых, остается для меня загадкой!

И мне интересно, если это поведениеобщий для других (всех?) базовых СУБД и / или драйверов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...