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 posted the code for NewMessagesRow() and AddMessagesRow() :) _db.Messages is just System.Data.TypedTableBase<MessagesRow> which extends DataTable. In Short, they are all just DataTable, and DataSet ..etc genereated by VS to support the strong types. – Vincent Sep 26, 2010 at 14:06

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.