我正在编写许多玩家连接的游戏服务器。 我将数据库加载到DataSet(强类型)。 每次玩家登录时,我都会使用TableAdapter向Messages表添加一个新行。
code
var newRow = _db.Messages.NewMessagesRow(); // _db is a strong-typed-dataset
{
newRow.Title = title;
newRow.Text = text;
newRow.ReceiverUID = receiverUID;
newRow.Deleted = false;
}
// I lock the _db.Messages, so it happens one at a time
lock ( _db.Messages )
{
_db.Messages.AddMessagesRow( newRow );
_adapterMessages.Connection.Open();
_adapterMessages.Update( newRow );
newRow.MessageID = (Int64)_adapterMessages.GetIdentity();
newRow.AcceptChanges();
_adapterMessages.Connection.Close();
}
NewMessagesRow()和AddMessagesRow()由VS自动生成。 我是通过添加一个DataSet项(.xsd文件)并将所有数据库表拖到它来完成的。
public MessagesRow NewMessagesRow() {
return ((MessagesRow)(this.NewRow()));
}
public void AddMessagesRow(MessagesRow row) {
this.Rows.Add(row);
}
_db是一个DataSet(强类型,由VS自动生成) _db.Messages是一个DataTable。
在测试中,我得到了
System.Data.NoNullAllowedException: Column 'Deleted' does not allow nulls.
at System.Data.DataColumn.CheckNullable(DataRow row)
at System.Data.DataTable.RaiseRowChanging(...)
at System.Data.DataTable.SetNewRecordWorker(...)
at System.Data.DataTable.InsertRow(...)
at System.Data.DataRowCollection.Add(DataRow row)
at Server.Database.MessagesDataTable.AddMessagesRow(MessagesRow row)
仅在上面的代码中调用AddMessagesRow(),并且我总是为Deleted列设置false,但仍然会收到此消息...
我不在其他任何地方使用_adapterMessages,但还有其他可以同时使用的适配器(_adapterUsers,_adapterMatches,...等)。
我不是每次都得到例外,但是如果服务器运行一段时间(例如> 30分钟)并且有大约1000个并发玩家,那么它就会发生。
任何帮助或建议将不胜感激。 谢谢:))
答案 0 :(得分:0)
我找出了这个问题的根本原因。 我认为DataTable.NewRow()是线程安全的,但事实并非如此。 在我在任何表上调用NewRow()之前,我必须完全锁定。
所以上面的代码需要改变如下:
lock ( _db.Messages )
{
var newRow = _db.Messages.NewMessagesRow();
{
newRow.Title = title;
newRow.Text = text;
newRow.ReceiverUID = receiverUID;
newRow.Deleted = false;
}
_db.Messages.AddMessagesRow( newRow );
_adapterMessages.Connection.Open();
_adapterMessages.Update( newRow );
newRow.MessageID = (Int64)_adapterMessages.GetIdentity();
newRow.AcceptChanges();
_adapterMessages.Connection.Close();
}
您可以在此问题上参考google search results ..