diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 92a9d6ce4..baf00f892 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -364,6 +364,7 @@ class MySQL_Threads_Handler bool forward_autocommit; bool enforce_autocommit_on_reads; bool autocommit_false_not_reusable; + bool autocommit_false_is_transaction; int max_allowed_packet; int throttle_connections_per_sec_to_hostgroup; int max_transaction_time; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index fc359adf8..37c27a2b4 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -630,6 +630,7 @@ __thread bool mysql_thread___multiplexing; __thread bool mysql_thread___forward_autocommit; __thread bool mysql_thread___enforce_autocommit_on_reads; __thread bool mysql_thread___autocommit_false_not_reusable; +__thread bool mysql_thread___autocommit_false_is_transaction; __thread bool mysql_thread___servers_stats; __thread bool mysql_thread___commands_stats; __thread bool mysql_thread___query_digests; @@ -732,6 +733,7 @@ extern __thread bool mysql_thread___multiplexing; extern __thread bool mysql_thread___forward_autocommit; extern __thread bool mysql_thread___enforce_autocommit_on_reads; extern __thread bool mysql_thread___autocommit_false_not_reusable; +extern __thread bool mysql_thread___autocommit_false_is_transaction; extern __thread bool mysql_thread___servers_stats; extern __thread bool mysql_thread___commands_stats; extern __thread bool mysql_thread___query_digests; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 51afe5a1d..6e15f6cd7 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1111,6 +1111,9 @@ bool MySQL_Session::handler_again___verify_init_connect() { } bool MySQL_Session::handler_again___verify_backend_autocommit() { + if (mysql_thread___forward_autocommit == true) { + return false; + } if (autocommit != mybe->server_myds->myconn->IsAutoCommit()) { // see case #485 if (mysql_thread___enforce_autocommit_on_reads == false) { diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 52f3cd0aa..e16d2d972 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -250,6 +250,7 @@ static char * mysql_thread_variables_names[]= { (char *)"forward_autocommit", (char *)"enforce_autocommit_on_reads", (char *)"autocommit_false_not_reusable", + (char *)"autocommit_false_is_transaction", (char *)"hostgroup_manager_verbose", (char *)"threshold_query_length", (char *)"threshold_resultset_size", @@ -400,6 +401,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.forward_autocommit=false; variables.enforce_autocommit_on_reads=false; variables.autocommit_false_not_reusable=false; + variables.autocommit_false_is_transaction=false; variables.query_digests=true; variables.query_digests_lowercase=false; variables.connpoll_reset_queue_length = 50; @@ -648,6 +650,7 @@ int MySQL_Threads_Handler::get_variable_int(char *name) { if (!strcasecmp(name,"forward_autocommit")) return (int)variables.forward_autocommit; if (!strcasecmp(name,"enforce_autocommit_on_reads")) return (int)variables.enforce_autocommit_on_reads; if (!strcasecmp(name,"autocommit_false_not_reusable")) return (int)variables.autocommit_false_not_reusable; + if (!strcasecmp(name,"autocommit_false_is_transaction")) return (int)variables.autocommit_false_is_transaction; if (!strcasecmp(name,"commands_stats")) return (int)variables.commands_stats; if (!strcasecmp(name,"query_digests")) return (int)variables.query_digests; if (!strcasecmp(name,"query_digests_lowercase")) return (int)variables.query_digests_lowercase; @@ -1004,6 +1007,9 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f if (!strcasecmp(name,"autocommit_false_not_reusable")) { return strdup((variables.autocommit_false_not_reusable ? "true" : "false")); } + if (!strcasecmp(name,"autocommit_false_is_transaction")) { + return strdup((variables.autocommit_false_is_transaction ? "true" : "false")); + } if (!strcasecmp(name,"commands_stats")) { return strdup((variables.commands_stats ? "true" : "false")); } @@ -1835,6 +1841,17 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t } return false; } + if (!strcasecmp(name,"autocommit_false_is_transaction")) { + if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) { + variables.autocommit_false_is_transaction=true; + return true; + } + if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) { + variables.autocommit_false_is_transaction=false; + return true; + } + return false; + } if (!strcasecmp(name,"commands_stats")) { if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) { variables.commands_stats=true; @@ -3245,6 +3262,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___forward_autocommit=(bool)GloMTH->get_variable_int((char *)"forward_autocommit"); mysql_thread___enforce_autocommit_on_reads=(bool)GloMTH->get_variable_int((char *)"enforce_autocommit_on_reads"); mysql_thread___autocommit_false_not_reusable=(bool)GloMTH->get_variable_int((char *)"autocommit_false_not_reusable"); + mysql_thread___autocommit_false_is_transaction=(bool)GloMTH->get_variable_int((char *)"autocommit_false_is_transaction"); mysql_thread___commands_stats=(bool)GloMTH->get_variable_int((char *)"commands_stats"); mysql_thread___query_digests=(bool)GloMTH->get_variable_int((char *)"query_digests"); mysql_thread___query_digests_lowercase=(bool)GloMTH->get_variable_int((char *)"query_digests_lowercase"); diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index d8c2eeffe..ba91ab09b 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -1471,6 +1471,12 @@ bool MySQL_Connection::IsActiveTransaction() { if (ret == false && (mysql)->net.last_errno) { ret = true; } + if (ret == false) { + bool r = ( mysql_thread___autocommit_false_is_transaction || mysql_thread___forward_autocommit ); + if ( r && (IsAutoCommit() == false) ) { + ret = true; + } + } } return ret; }