读书人

多个客户端同一时时执行相同的数据库操

发布时间: 2013-11-12 12:10:37 作者: rapoo

多个客户端同一时刻执行相同的数据库操作,发生死锁
halo 我们做了一组客户端(大约三十个),第天凌晨同一时刻按城市更新当天的数据,这时候经常报一个死锁的异常,我们解决了这个问题,但感觉不保险,如果客户端的量大到一定程序,这个问题还是会出现的,所以向各个求助有没有更好好的解决办法。

using (SqlConnection conn = new SqlConnection("..."))
{
SqlTransaction tran = null;

try
{
conn.Open();
tran = conn.BeginTransaction();

ExecuteNonQuery("update tabA set ...");// 按主键更新一行数据

StringBuilder sb = new StringBuilder();

sb.Append("delete from tab4 where city=@City;");
sb.Append("delete from tab3 where city=@City;");
sb.Append("delete from tab2 where city=@City;");
sb.Append("delete from tab1 where city=@City;");

ExecuteNonQuery(tran, sb.ToString(), parameter);// 这里异常

SqlBulkCopyData(tran, datatable1, "tab1");
SqlBulkCopyData(tran, datatable2, "tab2");
SqlBulkCopyData(tran, datatable3, "tab3");
SqlBulkCopyData(tran, datatable4, "tab4");

tran.Commit();
return true;
}
catch (Exception ex)
{
if (tran != null)
tran.Rollback();

LogHelper.RecordErrorLog(ex);
return false;
}
}

记录时间:2013-10-31 03:00:10
- 程序集名称:.Net SqlClient Data Provider
- 发生异常的方法:Void OnError(System.Data.SqlClient.SqlException, Boolean)
- 错误信息:事务(进程 ID 78)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
- 堆栈信息:
在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
[解决办法]
首先确定是那种锁。
造成死锁的原因是什么。


对数据的操作最合理的是单进程的线程执行(终级目标)。你得想办法使用统一的操作接口。
[解决办法]
对数据的操作最合理的是单进程的线性执行(终级目标)。你得想办法使用统一的操作接口。
[解决办法]
tran.BeginTransaction();

tran.Commit();之间你分别执行 ExecuteNonQuery()两次,一般一次就够了.应该把两个语句放到一起一次执行


[解决办法]
“多个客户端同一时刻执行相同的数据库操作”

这本身看起来就很可怕。

读书人网 >C#

热点推荐