Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm writing a game server to which many players connect.
I load up the DB into a DataSet(strong typed).
Every time a player logs in, I add a new row to Messages table using a TableAdapter.
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() and AddMessagesRow() is auto-generated by VS.
I did it by adding a DataSet item(.xsd file) and dragging all the DB tables to it.
public MessagesRow NewMessagesRow() {
return ((MessagesRow)(this.NewRow()));
public void AddMessagesRow(MessagesRow row) {
this.Rows.Add(row);
_db is a DataSet(strong-typed, auto-generated by VS)
_db.Messages is a DataTable.
while in testing, I get
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() gets called only in the code above, and I always set false for Deleted column, but still gets this message...
I don't use _adapterMessages anywhere else, but there are other adapters (_adapterUsers, _adapterMatches,... etc) that could be used concurrently.
I don't get the exception every time, but if the server runs for sometime(like > 30 min) with about 1000 concurrent players, it happens.
Any help or advices will be greatly appreciated.
Thanks :)
–
I figured out the root cause of this problem.
I thought DataTable.NewRow() was thread-safe, but it's not.
I have to lock exclusively before I call NewRow() on any tables.
so the code above needs to be changed like:
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();
You can refer to google search results on this issue..
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.