C#.NET MySQL(MariaDB)未保存数据但返回成功

C#.NET MySQL(MariaDB)未保存数据但返回成功,c#,mysql,asp.net,.net,mariadb,C#,Mysql,Asp.net,.net,Mariadb,在生产中间歇性地(在本地、开发或UAT环境中不可重复)数据将不会保存到数据库,即使MysqlClient返回成功并更新了行数 用于生产的应用程序服务器是Windows server 2008上的IIS 7 此应用程序服务器与两个独立的数据库服务器通信 UbuntuLinux服务器名4.15.0-23-generic>25 Ubuntu SMP周五18:02:16 UTC 2018 x86\u 64 x86\u 64 GNU/Linux上的一个 +-------------------------

在生产中间歇性地(在本地、开发或UAT环境中不可重复)数据将不会保存到数据库,即使MysqlClient返回成功并更新了行数

用于生产的应用程序服务器是Windows server 2008上的IIS 7

此应用程序服务器与两个独立的数据库服务器通信

Ubuntu
Linux服务器名4.15.0-23-generic>25 Ubuntu SMP周五18:02:16 UTC 2018 x86\u 64 x86\u 64 GNU/Linux上的一个
+-------------------------+----------------------------------+
|变量名称|值|
+-------------------------+----------------------------------+
|innodb|U版本| 5.6.39-83.1|
|协议|版本| 10|
|从属类型转换|
|版本| 10.1.34-MariaDB-0ubuntu0.18.04.1|
|版本|注释| Ubuntu 18.04|
|版本编译机器x86 64|
|版本编译操作系统debian linux gnu|
|版本(malloc)库(jemalloc系统)|
|版本| ssl |库| YaSSL 2.4.4|
|wsrep_补丁| wsrep_25.23版本|
+-------------------------+----------------------------------+

另一个在Fedora
Linux服务器名4.8.13-100.fc23.x86#u 64#1 SMP Fri Dec 9 14:51:40 UTC 2016 x86_64 x86_64 GNU/Linux上


+-------------------------+-----------------+
|变量名称|值|
+-------------------------+-----------------+
|innodb|U版本| 5.6.32-79.0|
|协议|版本| 10|
|从属类型转换|
|版本| 10.0.28-MariaDB|
|版本|注释| MariaDB服务器|
|版本编译机器x86 64|
|版本编译操作系统Linux|
|版本| malloc |库|系统|
+-------------------------+-----------------+

嘿,请不要问数据库服务器有多大不同。无论如何,他们都表现出同样的问题

该应用程序位于
.NET 4.5
中,并使用
MysqlConnector Mysql.Data dll 6.9.4
与这两个数据库进行通信

偶尔(在负载较重的情况下(根据系统通常获得的内容);大约25个并发用户),即使应用程序从代码(如
int x=Sqlcmd.ExecuteNonQuery())中获得成功,系统也会开始不保存对数据库的更改其中x是更新的行数

这将发生在非常基本的Mysql更新中,例如

MySqlConnection conn=newmysqlconnection(TheConnectionString());conn.Open();
尝试
{
string Query=“从USERID=”+USERID+“”的表中删除”;
MySqlCommand Sqlcmd=新的MySqlCommand(查询,连接);
Sqlcmd.CommandText=查询;
Sqlcmd.ExecuteNonQuery();
}
最后{if(conn!=null){conn.Close();conn.Dispose();}}

请忽略写得很差的sql语句,它很容易被sql注入

其他数据库交互方式(使用事务)也显示了相同的行为

    //Create and Instantiate the Connection
        sqlConnection = new MySqlConnection(strConnect);
        sqlConnection.Open();

        //With Transaction
        if (bWithTrans == true)
        {
            sqlTransaction = sqlConnection.BeginTransaction();
            //sqlTransaction.IsolationLevel = IsolationLevel.
            bRollBack = false; // Reset indicator
        }

        sqlCommand = new MySqlCommand(qryString, sqlConnection);
        sqlCommand.CommandText = qryString;

        //With Transaction
        if (bWithTrans == true)
        {
            sqlCommand.Transaction = sqlTransaction;
        }
...
...
       if (IsInTransaction())
        {
            if (bRollBack == true)
            {
                sqlTransaction.Rollback();
            }
            else
            {
                sqlTransaction.Commit();
            }
            sqlTransaction.Connection.Close();
            sqlTransaction.Connection.Dispose();
            sqlTransaction = null;
        }
我省略了上面的很多代码(比如关闭部分)。请忽略使用{}
语句缺少
(我99%确定每个连接都已关闭)

在未保存数据期间,以下内容出现在
select*from information\u schema.innodb\u trx

*************************** 1. row ***************************
                    trx_id: 302303150
                 trx_state: RUNNING
               trx_started: 2018-09-27 08:56:45
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 0
       trx_mysql_thread_id: 117343
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 0
     trx_lock_memory_bytes: 360
           trx_rows_locked: 0
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 10000
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 1. row ***************************
                    trx_id: 302303150
                 trx_state: RUNNING
               trx_started: 2018-09-27 08:56:45
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 0
       trx_mysql_thread_id: 117343
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 0
     trx_lock_memory_bytes: 360
           trx_rows_locked: 0
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 10000
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
看到
trx\u query:NULL
是非常奇怪的。。。我有一个脚本,每0.1秒打印一次这个表,只有当数据没有保存到数据库(但报告它是)时,它才会显示
trx\u query:NULL

在此期间,一个
show engine innodb status
在TRANSACTIONS部分中生成此消息

------------
TRANSACTIONS
------------
Trx id counter 147254697
Purge done for trx's n:o < 147254674 undo n:o < 0 state: running but idle
History list length 30
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 222904, OS thread handle 0x7f7a6e08b700, query id 617593737 localhost root init
show engine innodb status
---TRANSACTION 147254688, not started
MySQL thread id 222902, OS thread handle 0x7f7a23a5f700, query id 617593732 10.22.18.39 DB_NAME
---TRANSACTION 147254696, not started
MySQL thread id 222901, OS thread handle 0x7f7a239c9700, query id 617593736 10.22.18.39 DB_NAME
---TRANSACTION 147254644, not started
MySQL thread id 222900, OS thread handle 0x7f7a6e027700, query id 617593526 10.22.18.39 DB_NAME
---TRANSACTION 147254684, not started
MySQL thread id 222897, OS thread handle 0x7f7a6b4e9700, query id 617593709 10.22.18.39 DB_NAME
---TRANSACTION 147240473, not started
MySQL thread id 126445, OS thread handle 0x7f7a23af5700, query id 617593614 10.22.18.41 DB_NAME
---TRANSACTION 84024323, not started
MySQL thread id 1, OS thread handle 0x7f7a6e185700, query id 0 Waiting for background binlog tasks
---TRANSACTION 147254695, ACTIVE 1 sec fetching rows
mysql tables in use 1, locked 0
MySQL thread id 222898, OS thread handle 0x7f7a239fb700, query id 617593734 10.22.18.39 DB_NAME Sending data
SELECT COUNT(*) FROM TABLE I'M HIDING FOR PRIVACY
Trx read view will not see trx with id >= 147254696, sees < 147254696
Trx #rec lock waits 0 #table lock waits 0
Trx total rec lock wait time 0 SEC
Trx total table lock wait time 0 SEC

看到这么多的回滚真是太疯狂了。。。这可能是什么原因造成的。在我下面的评论中,我在app_server>db_server的tcpdump中显示了回滚,因此不是db发起这些回滚。

好的,我相信我发现了问题

应用程序经常调用的一个非常常见的存储过程中包含以下语句

START TRANSACTION;
SET AUTOCOMMIT = 0;
我从另一篇博文中了解到,
设置自动提交=0
是不必要的(很可能是我的罪魁祸首)

在我运行SP之前,
显示变量,如'autocommit'
在SP运行后返回
ON
,它说
OFF

我的理论是,调用SP的连接将其会话变量autocommit设置为
OFF
,然后返回到池中。后来,当连接从池中抓取该会话时,它开始回滚每个语句,因为
autocommit
仍处于关闭状态,并且没有显式的
COMMIT已发送

有人有这方面的经验吗

SELECT  COLUMN
    FROM  TABLE
    WHERE  COLUMN IN (
        SELECT  COLUMN
            FROM  TABLE
            WHERE  STATUSCODE = 3
                     )
    ORDER BY  COLUMN
-->

(如果确实有两个不同的表,那么请在您的问题中说明这一点。在这种情况下,改进的查询将需要一个
连接

-->


我猜是抛出异常并回滚事务。您应该添加一些日志来了解情况。@DavidLibido谢谢您的评论。即使不使用事务,数据也不会保存。我不能怀疑回滚,但是如果没有显式的
。rollback()
?。。。这是数据库服务器的tcpdump,它显示了一个回滚<代码>13:57:58.830419 IP 10.22.18.39.49804>10.22.18.246.3306:Flags[P],seq 242305:242318,ack 3237214,win 508,长度13 0x0000:4500 0035 06d2 4000 8006 baa8 0a16 1227 E.........0x0010:0a16 12f6 c28c 0cea c7e1 07c4 19e6 d958......X 0x0020:5018 01fc adfb 0
SELECT  COLUMN
    FROM  TABLE
    WHERE  COLUMN IN (
        SELECT  COLUMN
            FROM  TABLE
            WHERE  STATUSCODE = 3
                     )
    ORDER BY  COLUMN
SELECT column
    FROM table
    WHERE statuscode = 3
    ORDER BY column;
SELECT  COLUMN
    FROM  TABLE
    GROUP BY  COLUMN
    ORDER BY  COLUMN
SELECT DISTINCT column
    FROM table
    ORDER BY column
SELECT  COLUMN as Status
    FROM  TABLE
    WHERE  COLUMN <> 1
      AND  COLUMN <> 2
      AND  COLUMN <> 4
      AND  COLUMN <> 10
      AND  COLUMN <> 11
      AND  COLUMN <> 12
      AND  COLUMN <> 13
      AND  COLUMN <> 15
    ORDER BY  REC_NUM
SELECT column AS Status
    FROM table
    WHERE column NOT IN (1,2,4,10,11,12,13,15)
    ORDER BY rec_num
Why do this; the answer is obviously 'DB_NAME':

SELECT column FROM table WHERE column = 'DB_NAME'.