Мы, похоже, пришли к странной проблеме, где два одновременных запроса к нашей службе фактически используют одно и то же соединение с БД.ServiceStack/FluentNHibernate/MySQL - То же соединение, используемое двумя параллельными запросами
Наша настройка - ServiceStack + NHibernate + FluentNHibernate + MySQL. Я создал небольшой тест, который воссоздает проблему:
public class AppHost : AppHostBase
{
private ISessionFactory _sessionFactory;
public AppHost() : base("Lala Service", typeof(AppHost).Assembly)
{
}
public override void Configure(Container container)
{
_sessionFactory = Fluently.Configure()
.Database(MySQLConfiguration.Standard.ConnectionString(conn =>
conn.Server("localhost").Username("lala").Password("lala").Database("lala")))
.Mappings(mappings => mappings.AutoMappings.Add(
AutoMap.Assembly(GetType().Assembly).Where(t => t == typeof(Lala))
.Conventions.Add(DefaultLazy.Never(), DefaultCascade.All())))
.BuildSessionFactory();
container.Register(c => _sessionFactory.OpenSession()).ReusedWithin(ReuseScope.Request);
}
}
public class Lala
{
public int ID { get; set; }
public string Name { get; set; }
}
[Route("/lala")]
public class LalaRequest
{
}
public class LalaReseponse
{
}
public class LalaService : Service
{
private ISession _session;
public ISession Session1
{
get { return _session; }
set { _session = value; }
}
public LalaReseponse Get(LalaRequest request)
{
var lala = new Lala
{
Name = Guid.NewGuid().ToString()
};
_session.Persist(lala);
_session.Flush();
lala.Name += " XXX";
_session.Flush();
return new LalaReseponse();
}
}
Я ударил эту услугу 10 раз concurrenly с помощью Ajax, как так:
<script type="text/javascript">
for (i = 0; i < 10; i++) {
console.log("aa");
$.ajax({
url: '/lala',
dataType: 'json',
cache: false
});
}
</script>
Результат:
- Количество соединений открыть < 10.
- Не все записи обновлены.
- В некоторых случаях -
StaleObjectStateException
брошен - если я удалю записи.
Причина в том, что соединения повторно используются двумя параллельными запросами, а затем LAST_INSERT_ID() указывает идентификатор неправильной строки, поэтому два запроса обновляют одну и ту же строку.
Вкратце: это полный беспорядок, и это явно разделяет соединение БД между запросами.
Вопрос: Почему? Как мне настроить данные так, чтобы каждый запрос получил свое собственное соединение из пула соединений?