[英]C# .NET MySQL (MariaDB) Not Saving Data Yet Returning Sucess
間歇性地生產(在本地,開發或UAT環境中不可重復)數據將不會保存到數據庫,即使MysqlClient返回成功並且行數已更新。
用於生產的應用程序服務器是IIS 7 on Windows Server 2008
此應用程序服務器與2個單獨的數據庫服
一個在Ubuntu Linux servername 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 18:02:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
+-------------------------+----------------------------------+ | Variable_name | Value | +-------------------------+----------------------------------+ | innodb_version | 5.6.39-83.1 | | protocol_version | 10 | | slave_type_conversions | | | version | 10.1.34-MariaDB-0ubuntu0.18.04.1 | | version_comment | Ubuntu 18.04 | | version_compile_machine | x86_64 | | version_compile_os | debian-linux-gnu | | version_malloc_library | system jemalloc | | version_ssl_library | YaSSL 2.4.4 | | wsrep_patch_version | wsrep_25.23 | +-------------------------+----------------------------------+
+-------------------------+----------------------------------+ | Variable_name | Value | +-------------------------+----------------------------------+ | innodb_version | 5.6.39-83.1 | | protocol_version | 10 | | slave_type_conversions | | | version | 10.1.34-MariaDB-0ubuntu0.18.04.1 | | version_comment | Ubuntu 18.04 | | version_compile_machine | x86_64 | | version_compile_os | debian-linux-gnu | | version_malloc_library | system jemalloc | | version_ssl_library | YaSSL 2.4.4 | | wsrep_patch_version | wsrep_25.23 | +-------------------------+----------------------------------+
另一個在Fedora Linux servername 4.8.13-100.fc23.x86_64 #1 SMP Fri Dec 9 14:51:40 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
+-------------------------+-----------------+ | Variable_name | Value | +-------------------------+-----------------+ | innodb_version | 5.6.32-79.0 | | protocol_version | 10 | | slave_type_conversions | | | version | 10.0.28-MariaDB | | version_comment | MariaDB Server | | version_compile_machine | x86_64 | | version_compile_os | Linux | | version_malloc_library | system | +-------------------------+-----------------+
嘿,請不要問一下完全不同的數據庫服務器。 無論如何,他們都表現出同樣的問題。
該應用程序在.NET 4.5
並使用MysqlConnector Mysql.Data dll 6.9.4
與兩個數據庫進行通信。
偶爾(在負載很重的情況下(根據系統通常會得到的);大約25個並發用戶)系統將開始不保存對數據庫的更改,即使應用程序從代碼中獲得成功,例如int x = Sqlcmd.ExecuteNonQuery();
其中x是更新的行數。
這將發生非常基本的Mysql更新,如
MySqlConnection conn = new MySqlConnection(TheConnectionString()); conn.Open(); try { string Query = "DELETE FROM A_TABLE WHERE USERID = '" + UserID + "'"; MySqlCommand Sqlcmd = new MySqlCommand(Query, conn); Sqlcmd.CommandText = Query; Sqlcmd.ExecuteNonQuery(); } finally { 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;
}
我從上面省略了很多代碼(例如結束部分。)請忽略using {}
語句的缺失(我99%確定每個連接都已關閉。)
在未保存數據的時間內, select * from information_schema.innodb_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_query: NULL
是非常奇怪的trx_query: NULL
...我有一個腳本每0.1秒打印一次這個表,並且它只會在數據沒有保存到數據庫時顯示trx_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
我沒有看到任何陷入僵局的事情。
我試過的......
.beginTransaction()
東西,所以在每個ExecuteNonQuery()
之后執行默認的AUTO-COMMIT 有人有想法么?
謝謝
**編輯這里是記錄到文件的查詢日志(我編輯了sql以刪除表/列名稱以保護隱私)
245133 Query ROLLBACK
245671 Connect root@localhost as anonymous on
245671 Query select * from information_schema.innodb_trx
244093 Query ROLLBACK
245671 Quit
245133 Init DB DB_NAME
245133 Query SELECT `DESC` as Status FROM TABLE WHERE REC_NUM != 2 ORDER BY `REC_NUM`
245133 Query ROLLBACK
244093 Init DB DB_NAME
244093 Query SELECT COLUMN FROM TABLE WHERE COLUMN IN (SELECT COLUMN FROM TABLE WHERE STATUSCODE = 3) ORDER BY COLUMN
244093 Query ROLLBACK
245133 Init DB DB_NAME
245133 Query SELECT COLUMN FROM TABLE GROUP BY COLUMN ORDER BY COLUMN
245133 Query ROLLBACK
244093 Init DB DB_NAME
244093 Query 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
244093 Query ROLLBACK
245133 Init DB DB_NAME
245133 Query SELECT COLUMN FROM TABLE WHERE COLUMN = 'DB_NAME'
245133 Query ROLLBACK
245248 Query ROLLBACK
244093 Init DB DB_NAME
245133 Init DB DB_NAME
很難看到這么多ROLLBACKS ......可能是什么導致了這一點。 在下面的評論中,我在app_server> db_server中的tcpdump中顯示ROLLBACK,因此不是啟動這些回滾的數據庫。
好吧,我相信我發現了問題。
應用程序調用的一個非常常見的存儲過程中有這個聲明......
START TRANSACTION;
SET AUTOCOMMIT = 0;
我從另一篇文章中了解到SET AUTOCOMMIT = 0
是不必要的(很可能是我的罪魁禍首。)
在我運行SP之前,在SP運行后show variables like 'autocommit'
返回ON
,它說OFF
我的理論是連接調用SP將其autocommit的會話變量設置為OFF
然后返回到池中。 稍后,當一個連接從池中獲取該會話時,它開始回滾每個語句,因為autocommit
仍然關閉,並且沒有顯式的COMMIT;
曾被送過。
有人有這方面的經驗嗎?
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;
(如果確實有兩個不同的表,那么請在你的問題中明確說明。在這種情況下,改進的查詢需要一個JOIN
。)
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'.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.