2012-01-12 34 views
5

Tôi đọc trong docs:Giao dịch có bắt đầu ngay cả khi CHỌN không?

... kể từ khi giao dịch bắt đầu khi một con trỏ thực hiện một truy vấn, nhưng kết thúc khi COMMIT hoặc ROLLBACK được thực hiện bởi các đối tượng Connection.

import MySQLdb 

db = MySQLdb.connect(user="root", db="test") 
c = db.cursor() 
c.execute("SELECT * FROM books") 
print c.fetchall() 

Tôi nghi ngờ rằng MySQLdb bắt đầu một giao dịch thậm chí trên các truy vấn mà không sửa đổi dữ liệu (như SELECT), bởi vì rất khó để biết nếu một truy vấn chỉ đọc dữ liệu và không viết nó.

  1. Có đúng không?
  2. Nếu có, điều này có nghĩa là tôi nên làm cursor.commit() sau mỗi truy vấn, để đảm bảo rằng không có bảng nào bị khóa?
  3. Các vấn đề khác mà tôi không biết?

Cảm ơn bạn

Trả lời

3

Vâng, một tuyên bố SELECT được như khác để giao dịch bắt đầu.

Nếu bạn muốn tránh điều này, bạn có thể làm một cái gì đó như thế:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 
SELECT * FROM books ; 
COMMIT ; 

Cụ thể:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 

nói rằng các chỉ dẫn sau đây có thể đọc các hàng đã được sửa đổi nhưng điều đó chưa nhận được COMMIT. Loại giao dịch đó không có khóa độc quyền.

Phần thứ hai SELECT * FROM books ; rõ ràng là một SQL statement và phần thứ ba COMMIT ; kết thúc giao dịch và đặt thành "vĩnh viễn". Trong trường hợp đó không viết được thực hiện, do đó COMMIT chỉ được sử dụng để kết thúc giao dịch và

+0

Ông có thể vui lòng giải thích ví dụ của bạn, và tại sao 'commit' vẫn cần thiết? – warvariuc

+0

@warwaruk: câu hỏi này có được cập nhật không? Bởi vì tôi nhớ rằng nó khác. – DonCallisto

+0

Không, nó không được cập nhật ... – warvariuc

1
  1. nó là đúng, nhưng nó cũng tự động cam kết sau mỗi lần truy vấn, vì mysql khách hàng bắt đầu với autocommit=1 theo mặc định

  2. bạn không nên, vì SELECT không giữ bất kỳ khóa nào sau khi câu lệnh được thực hiện. Trong thực tế, các cam kết rõ ràng thậm chí có thể làm chậm đáng kể.

  3. Chỉ có thể có ích: Why connection in Python's DB-API does not have "begin" operation?

+0

'autocommit = 1' không đúng đối với Pythons' MySQLdb'! Bạn phải đặt điều này một cách rõ ràng.Đó là một nguồn phổ biến cho sự hiểu lầm trong Python a la "Dữ liệu mà tôi vừa chèn vào đâu?". –

+1

@ ocaso-protal, hmm, đúng. Tại sao tôi vẫn nghĩ như vậy, đã loại bỏ các thiết lập paramerer 'init_command' autocommit = 0 từ các thiết lập kết nối của tôi một thời gian dài trước đây? – newtover

Các vấn đề liên quan