Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

root/tags/1.4.0/storage/msaccessthreads.py

Revision 88 (checked in by fumanchu, 7 years ago)

Set eol-style:native on all .py files.

  • Property svn:eol-style set to native
Line 
1 """This proves that MS Access is single-threaded. If you use multiple
2 Python threads, you must synchronize them by closing their Connections
3 in order. In the example code, because we do not explicitly close the
4 first connection before starting the second thread, the data written
5 in the second thread is not reflected in the dataset of the first thread.
6
7
8 If Access allowed threads properly, the output would be:
9
10 Attempt: 0 Object1 Mod1 Mod1
11 Attempt: 1 Object1 Mod1 Mod1
12 Attempt: 2 Object1 Mod1 Mod1
13
14 Instead, it's:
15
16 Attempt: 0 Object1 Mod1 Object1
17 Attempt: 1 Object1 Mod1 Object1
18 Attempt: 2 Object1 Mod1 Mod1
19
20 """
21
22 import time
23 import win32com.client
24 import pywintypes
25 import threading
26 import os
27
28 def get_conn():
29     conn = win32com.client.Dispatch(r'ADODB.Connection')
30     conn.Open(c)
31     return conn
32
33 c = "PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=test.mdb;"
34
35 def update_record():
36     conn = get_conn()
37     conn.Execute('UPDATE test SET Name = "Mod1" WHERE ID = 1;')
38     print_table(conn)
39     if attempt == 1:
40         conn.Close()
41
42 def print_table(conn):
43     res = win32com.client.Dispatch(r'ADODB.Recordset')
44     res.Open("SELECT * FROM test;", conn)
45     data = []
46     if not (res.EOF and res.BOF):
47         data = res.GetRows()
48     res.Close()
49     print data[0][0],
50
51 def main_thread():
52     print "\nAttempt: %s" % attempt,
53    
54     try:
55         cat = win32com.client.Dispatch(r'ADOX.Catalog')
56         cat.Create(c)
57         cat.ActiveConnection.Close()
58     except pywintypes.com_error:
59         pass
60     cat = None
61    
62     conn = get_conn()
63     conn.Execute('CREATE TABLE test (Name VARCHAR(255), ID INTEGER);')
64     conn.Execute('INSERT INTO test VALUES ("Object1", 1);')
65     print_table(conn)
66    
67     t = threading.Thread(target=update_record)
68     t.start()
69     t.join()
70    
71     if attempt == 2:
72         # 5 seconds seems to be the lower limit.
73         # Anything less, and we get the old data.
74         time.sleep(5)
75     if attempt == 3:
76         conn = get_conn()
77    
78     print_table(conn)
79     conn.Close()
80
81 if __name__ == '__main__':
82     for attempt in range(4):
83         try:
84             main_thread()
85         finally:
86             try:
87                 os.remove("test.mdb")
88             except OSError:
89                 pass
90
Note: See TracBrowser for help on using the browser.