Bug #102053 | Python sql connection pool not updating after query with zero results | ||
---|---|---|---|
Submitted: | 22 Dec 2020 19:37 | Modified: | 17 Mar 2021 4:32 |
Reporter: | James Morris | Email Updates: | |
Status: | No Feedback | Impact on me: | |
Category: | Connector / Python | Severity: | S1 (Critical) |
Version: | 8.0.22 | OS: | Ubuntu (18.04) |
Assigned to: | CPU Architecture: | x86 | |
Tags: | connection-pool, python |
[22 Dec 2020 19:37]
James Morris
[23 Dec 2020 6:23]
MySQL Verification Team
Hello James Morris, Thank you for the report! regards, Umesh
[16 Feb 2021 0:16]
Jose Israel Gomez Delgado
Hello James, and thanks for submit your bug. The behavior you described is not a bug and is an expected behavior due to the default value of the `autocommit` option, which is set to False by default, in short by setting `autocommit=True` or adding `'autocommit':True` to your connection settings dictionary object you will get a more aligned behavior to your expectations. However, please allow me to try to explain why you got this behavior even after you have invoked the `commit()` method after your insert statement and how you can get the same results with the `autocommit` option set to False. By default, `autocommit` option is set to False, whenever you use a pool of connections or a single connection; this allow to each connection work as in a different session, and any change will not be applied or see be visible by other sessions until commit is invoked. And in addition, that for each session it is very important to invoke or execute `commit()` statement but not just to commit the changes on this session, it becomes very important in order of accept the changes committed by other sessions after this session were started. Furthermore, while implementing pooling due to the nature of how it works internally because on pooling the connections are not fully close and reopen; they are just cleanup in order of be reused later, which is faster than open new connections. If we apply this theory adding a commit call prior of the `select` statement, will do the trick -----------8<--------- for _ in range(12): con = mysql.connector.connect(pool_name="mypool") cur = con.cursor() con.commit() # This commit accepts the inserts by the other session. cur.execute("SELECT id FROM test WHERE id = '123';") result = cur.fetchall() cur.close() con.close() print(result) ----------->8--------- and gives us the expected output: [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] [('123',)] In the following script, at the run_test() method you can find the same test code but with the call to `commit()` prior the select: #!/usr/bin/python import mysql.connector def create_clean(): # db has 1 empty table 'test' with one varchar field 'id' # Drop table if exists, and create it new con1 = mysql.connector.connect(**dbvars) cur1 = con1.cursor() stmt_drop = "DROP TABLE IF EXISTS test" cur1.execute(stmt_drop) stmt_create = ( "CREATE TABLE test (" "id VARCHAR(30) DEFAULT '' NOT NULL, " "PRIMARY KEY (id))" ) cur1.execute(stmt_create) cur1.execute("COMMIT;") return True def insert(): con1 = mysql.connector.connect(**dbvars) cur1 = con1.cursor() cur1.execute("INSERT INTO test VALUES ('789');") cur1.execute("COMMIT;") return True def run_test(): con = mysql.connector.connect(pool_name="mypool", pool_size=3, pool_reset_session=False, **dbvars) cur = con.cursor() cur.execute("SELECT id FROM test WHERE id = '123';") result = cur.fetchall() cur.close() con.close() con = mysql.connector.connect(pool_name="mypool") cur = con.cursor() cur.execute("INSERT INTO test VALUES ('123');") con.commit() cur.close() con.close() for _ in range(12): con = mysql.connector.connect(pool_name="mypool") cur = con.cursor() con.commit() # This commit accepts the inserts by the other session. cur.execute("SELECT id FROM test WHERE id = '123';") result = cur.fetchall() cur.close() con.close() print(result) if __name__ == '__main__': dbvars = { 'host':'localhost', 'user':'root','passwd':'', 'db':'test', "port": 4824, #"use_pure":True, #'autocommit':True } create_clean() run_test() I hope this behavior is clarified now, finally once again thank you for open a bug and use C/py.
[18 Mar 2021 1:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".