即使MysqlClient返回成功且已更新的行数,生产中的间歇性数据(在本地,开发或UAT环境中也不能重复)不会保存到数据库中。
用于生产的应用程序服务器为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 |
+-------------------------+----------------------------------+
上使用一个
另一个在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个并发用户),即使应用程序从诸如{{1 }},其中x是已更新的行数。
这将通过非常基本的Mysql更新(例如
)发生 int x = Sqlcmd.ExecuteNonQuery();
请忽略明显易写的sql语句,该语句易于sql注入。
其他数据库交互方式(使用事务)也显示相同的行为。
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(); } }
我从上面省略了很多代码(例如,结束部分。)请忽略缺少 //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%确信每个连接都是关闭的。)
在未保存数据期间,using {}
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
很奇怪...我有一个脚本,每隔0.1秒打印一次此表,并且只有在数据没有保存到数据库时,它才会显示trx_query: NULL
(至今)报告它是。)
这一次,trx_query: NULL
在TRANSACTIONS部分产生了这个结果...
show engine innodb status
我没有看到任何僵局。
我尝试过的...
------------
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()
有人有什么想法吗?
谢谢
**这里编辑是记录到文件中的查询日志(为了保护隐私,我编辑了sql以删除表/列名)
ExecuteNonQuery()
疯狂地看到这么多回滚...可能是什么原因造成的。在下面的评论中,我在app_server> db_server的tcpdump中显示ROLLBACK,所以不是数据库启动这些回滚。
答案 0 :(得分:0)
好的,我相信我找到了问题。
应用程序经常调用的非常常见的存储过程中包含以下语句...
#include <iostream>
#include <algorithm>
using namespace std;
struct matrix{
int* data; //since it is a 1d array which will later be stored in the matrix
int row, col;
};
void createMatrix(int row, int col, int num[], matrix& mat); //by reference so that I fetch it by address from memory
matrix operator+ (matrix mat1, matrix mat2){ //Addition
matrix mat;
for(int i = 0; i < max(mat1.row*mat1.col, mat2.row*mat2.col); i++){
mat.data[i] = mat1.data[i] + mat2.data[i];
}
return mat;
}
matrix operator- (matrix mat1, matrix mat2){ //Subtraction
matrix mat;
for(int i = 0;i < max(mat1.row*mat1.col, mat2.row*mat2.col); i++){
mat.row = mat1.row - mat2.row;
}
return mat;
}
ostream operator<< (ostream& out, matrix mat){
for(int i = 0; i < ((mat.row)*(mat.col)); i++){
if(i % mat.row == 0 ){
cout<<endl;
}
else{out<<mat.data[i]<<" ";}
}
}
int main()
{
int row1, col1;
int row2, col2;
cout<<"Enter Rows of first matrix: "; cin>>row1;
cout<<"Enter Cols of first matrix: "; cin>>col1;
cout<<"Enter Rows of second matrix: "; cin>>row2;
cout<<"Enter Cols of second matrix: "; cin>>col2;
int arr1[row1*col1], arr2[row2*col2];
cout<<"Enter the values you which to add in the first matrix: ";
for(int i = 0; i < row1*col1; i++){
cin>>arr1[i];
}
cout<<"Enter the values you which to add in the second matrix: ";
for(int i = 0; i < row2*col2; i++){
cin>>arr2[i];
}
matrix mat1, mat2, mat3;
createMatrix(row1, col1, arr1, mat1);
createMatrix(row2, col2, arr2, mat2);
mat3 = mat1 + mat2;
cout<<mat3;
return 0;
}
void createMatrix(int row, int col, int num[], matrix& mat){
mat.row = row;
mat.col = col;
mat.data = new int [col * row]; //We are trying to make a matrix from a 1d array, so we will stretch the matrix -which is a 2d array
for(int i = 0; i < col * row; i++){ //in 1-D of size row *col
mat.data[i] = num[i]; //Depending on the parameter the data array will be filled dynamically
}
}
我从另一篇文章中了解到START TRANSACTION;
SET AUTOCOMMIT = 0;
是不必要的(很可能是我的罪魁祸首。)
在我运行SP之前,SET AUTOCOMMIT = 0
在运行SP后返回了show variables like 'autocommit'
,它说ON
我的理论是,连接调用SP将其自动提交的会话变量设置为OFF
,然后返回到池中。稍后,当连接从池中获取该会话时,它便开始回滚每个语句,因为OFF
仍处于关闭状态,并且从未发送过任何明确的autocommit
。
有人对此有经验吗?
答案 1 :(得分: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;
(如果确实有两个不同的表,则请在您的问题中明确指出。在这种情况下,改进的查询将需要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'.