@@ -32,10 +32,18 @@ class TestAsyncTx(tb.AsyncQueryTestCase):
32
32
CREATE TYPE test::TransactionTest EXTENDING std::Object {
33
33
CREATE PROPERTY name -> std::str;
34
34
};
35
- '''
36
35
37
- TEARDOWN = '''
38
- DROP TYPE test::TransactionTest;
36
+
37
+ CREATE TYPE test::Tmp {
38
+ CREATE REQUIRED PROPERTY tmp -> std::str;
39
+ };
40
+ CREATE TYPE test::TmpConflict {
41
+ CREATE REQUIRED PROPERTY tmp -> std::str {
42
+ CREATE CONSTRAINT exclusive;
43
+ }
44
+ };
45
+
46
+ CREATE TYPE test::TmpConflictChild extending test::TmpConflict;
39
47
'''
40
48
41
49
async def test_async_transaction_regular_01 (self ):
@@ -104,3 +112,61 @@ async def test_async_transaction_exclusive(self):
104
112
):
105
113
await asyncio .wait_for (f1 , timeout = 5 )
106
114
await asyncio .wait_for (f2 , timeout = 5 )
115
+
116
+
117
+ async def _try_bogus_rr_tx (self , con , first_try ):
118
+ # A transaction that needs to be serializable
119
+ async for tx in con .transaction ():
120
+ async with tx :
121
+ res1 = await tx .query_single ('''
122
+ select {
123
+ ins := (insert test::Tmp { tmp := "test1" }),
124
+ level := sys::get_transaction_isolation(),
125
+ }
126
+ ''' )
127
+ # If this is the second time we've tried to run this
128
+ # transaction, then the cache should ensure we *only*
129
+ # try Serializable.
130
+ if not first_try :
131
+ self .assertEqual (res1 .level , 'Serializable' )
132
+
133
+ res2 = await tx .query_single ('''
134
+ select {
135
+ ins := (insert test::TmpConflict {
136
+ tmp := <str>random()
137
+ }),
138
+ level := sys::get_transaction_isolation(),
139
+ }
140
+ ''' )
141
+
142
+ # N.B: res1 will be RepeatableRead on the first
143
+ # iteration, maybe, but contingent on the second query
144
+ # succeeding it will be Serializable!
145
+ self .assertEqual (res1 .level , 'Serializable' )
146
+ self .assertEqual (res2 .level , 'Serializable' )
147
+
148
+ async def test_async_transaction_prefer_rr (self ):
149
+ if (
150
+ str (self .server_version .stage ) != 'dev'
151
+ and (self .server_version .major , self .server_version .minor ) < (6 , 5 )
152
+ ):
153
+ self .skipTest ("DML in RepeatableRead not supported yet" )
154
+ con = self .client .with_transaction_options (
155
+ edgedb .TransactionOptions (
156
+ isolation = edgedb .IsolationLevel .PreferRepeatableRead
157
+ )
158
+ )
159
+ # A transaction that needs to be serializable
160
+ await self ._try_bogus_rr_tx (con , first_try = True )
161
+ await self ._try_bogus_rr_tx (con , first_try = False )
162
+
163
+ # And one that doesn't
164
+ async for tx in con .transaction ():
165
+ async with tx :
166
+ res = await tx .query_single ('''
167
+ select {
168
+ ins := (insert test::Tmp { tmp := "test" }),
169
+ level := sys::get_transaction_isolation(),
170
+ }
171
+ ''' )
172
+ self .assertEqual (str (res .level ), 'RepeatableRead' )
0 commit comments