我只有一个SQL Server应该锁定的资源,即Company表,但以下控制台应用程序是死锁的。为什么呢?
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataAccess;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Context;
using NHibernate.Tool.hbm2ddl;
namespace NhibernatePlayground
{
class Program
{
private static ISessionFactory _sessionFactory;
private static Configuration _configuration;
private static int TotalThreadCount = 20;
private static int LoopCount = 1000;
private static void Main(string[] args)
{
//App_Start.NHibernateProfilerBootstrapper.PreStart();
_configuration = BuildConfiguration();
var se = new SchemaExport(_configuration);
se.Create(false, true);
_sessionFactory = _configuration.BuildSessionFactory();
int companyId = Seed();
Stopwatch sw = new Stopwatch();
sw.Start();
Task[] tasks = new Task[TotalThreadCount];
for (int i = 0; i < TotalThreadCount; i ++)
{
tasks[i] = Task.Factory.StartNew(() => IncreaseEmployeeCount(LoopCount, companyId));
}
//Block until all tasks complete.
Task.WaitAll(tasks);
sw.Stop();
Console.WriteLine("Employee Count: " + GetEmployeeCount(companyId));
Console.WriteLine("Total Milliseconds: " + sw.ElapsedMilliseconds);
Console.ReadKey();
}
private static Configuration BuildConfiguration()
{
Configuration configuration = new Configuration();
configuration.Configure(); // A
configuration.AddAssembly(typeof(Company).Assembly); // B
return configuration;
}
private static void IncreaseEmployeeCount(int count, int companyId)
{
for (int i = 0; i < count; i++)
{
using (ISession _session = _sessionFactory.OpenSession())
{
using (ITransaction _transaction = _session.BeginTransaction(IsolationLevel.Serializable))
{
var company = _session.Get<Company>(companyId);
company.EmployeeCount++;
_session.Save(company);
_transaction.Commit();
}
}
}
}
private static int Seed()
{
using (ISession _session = _sessionFactory.OpenSession())
{
using (ITransaction _transaction = _session.BeginTransaction())
{
Company company = new Company
{
CompanyName = "Angus"
};
_session.Save(company);
_transaction.Commit();
return company.Id;
}
}
}
private static int GetEmployeeCount(int companyId)
{
using (ISession _session = _sessionFactory.OpenSession())
{
using (ITransaction _transaction = _session.BeginTransaction())
{
Company company = _session.Get<Company>(companyId);
return company.EmployeeCount;
}
}
}
}
}