Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
ZODB
Commits
99cbe353
Commit
99cbe353
authored
Sep 02, 2010
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented checkCurrentSerialInTransaction for the basic storages.
parent
82c3c0fe
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
109 additions
and
1 deletion
+109
-1
src/ZODB/BaseStorage.py
src/ZODB/BaseStorage.py
+13
-0
src/ZODB/DemoStorage.py
src/ZODB/DemoStorage.py
+4
-0
src/ZODB/MappingStorage.py
src/ZODB/MappingStorage.py
+4
-0
src/ZODB/tests/BasicStorage.py
src/ZODB/tests/BasicStorage.py
+86
-0
src/ZODB/tests/test_storage.py
src/ZODB/tests/test_storage.py
+2
-1
No files found.
src/ZODB/BaseStorage.py
View file @
99cbe353
...
@@ -399,6 +399,19 @@ def copy(source, dest, verbose=0):
...
@@ -399,6 +399,19 @@ def copy(source, dest, verbose=0):
dest
.
tpc_finish
(
transaction
)
dest
.
tpc_finish
(
transaction
)
# defined outside of BaseStorage to facilitate independent reuse.
# just depends on _transaction attr and getTid method.
def
checkCurrentSerialInTransaction
(
self
,
oid
,
serial
,
transaction
):
if
transaction
is
not
self
.
_transaction
:
raise
POSException
.
StorageTransactionError
(
self
,
transaction
)
committed_tid
=
self
.
getTid
(
oid
)
if
committed_tid
!=
serial
:
raise
POSException
.
ReadConflictError
(
oid
=
oid
,
serials
=
(
committed_tid
,
serial
))
BaseStorage
.
checkCurrentSerialInTransaction
=
checkCurrentSerialInTransaction
class
TransactionRecord
(
object
):
class
TransactionRecord
(
object
):
"""Abstract base class for iterator protocol"""
"""Abstract base class for iterator protocol"""
...
...
src/ZODB/DemoStorage.py
View file @
99cbe353
...
@@ -24,6 +24,7 @@ import random
...
@@ -24,6 +24,7 @@ import random
import
weakref
import
weakref
import
tempfile
import
tempfile
import
threading
import
threading
import
ZODB.BaseStorage
import
ZODB.blob
import
ZODB.blob
import
ZODB.interfaces
import
ZODB.interfaces
import
ZODB.MappingStorage
import
ZODB.MappingStorage
...
@@ -304,6 +305,9 @@ class DemoStorage(object):
...
@@ -304,6 +305,9 @@ class DemoStorage(object):
oid
,
oldserial
,
data
,
blobfilename
,
''
,
transaction
)
oid
,
oldserial
,
data
,
blobfilename
,
''
,
transaction
)
raise
raise
checkCurrentSerialInTransaction
=
(
ZODB
.
BaseStorage
.
checkCurrentSerialInTransaction
)
def
temporaryDirectory
(
self
):
def
temporaryDirectory
(
self
):
try
:
try
:
return
self
.
changes
.
temporaryDirectory
()
return
self
.
changes
.
temporaryDirectory
()
...
...
src/ZODB/MappingStorage.py
View file @
99cbe353
...
@@ -21,6 +21,7 @@ import BTrees
...
@@ -21,6 +21,7 @@ import BTrees
import
cPickle
import
cPickle
import
time
import
time
import
threading
import
threading
import
ZODB.BaseStorage
import
ZODB.interfaces
import
ZODB.interfaces
import
ZODB.POSException
import
ZODB.POSException
import
ZODB.TimeStamp
import
ZODB.TimeStamp
...
@@ -261,6 +262,9 @@ class MappingStorage(object):
...
@@ -261,6 +262,9 @@ class MappingStorage(object):
return
self
.
_tid
return
self
.
_tid
checkCurrentSerialInTransaction
=
(
ZODB
.
BaseStorage
.
checkCurrentSerialInTransaction
)
# ZODB.interfaces.IStorage
# ZODB.interfaces.IStorage
@
ZODB
.
utils
.
locked
(
opened
)
@
ZODB
.
utils
.
locked
(
opened
)
def
tpc_abort
(
self
,
transaction
):
def
tpc_abort
(
self
,
transaction
):
...
...
src/ZODB/tests/BasicStorage.py
View file @
99cbe353
...
@@ -199,3 +199,89 @@ class BasicStorage:
...
@@ -199,3 +199,89 @@ class BasicStorage:
self
.
_storage
.
tpc_vote
(
t
)
self
.
_storage
.
tpc_vote
(
t
)
self
.
_storage
.
tpc_finish
(
t
)
self
.
_storage
.
tpc_finish
(
t
)
t
.
commit
()
t
.
commit
()
def
check_checkCurrentSerialInTransaction
(
self
):
oid
=
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf0
'
tid
=
self
.
_dostore
(
oid
)
tid2
=
self
.
_dostore
(
oid
,
revid
=
tid
)
# stale read
transaction
.
begin
()
t
=
transaction
.
get
()
self
.
_storage
.
tpc_begin
(
t
)
try
:
self
.
_storage
.
store
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf1
'
,
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
,
'x'
,
''
,
t
)
self
.
_storage
.
checkCurrentSerialInTransaction
(
oid
,
tid
,
t
)
self
.
_storage
.
tpc_vote
(
t
)
except
POSException
.
ReadConflictError
,
v
:
self
.
assert_
(
v
.
oid
)
==
oid
self
.
assert_
(
v
.
serials
==
(
tid2
,
tid
))
else
:
self
.
assert_
(
False
,
"No conflict error"
)
self
.
_storage
.
tpc_abort
(
t
)
# non-stale read, no stress. :)
transaction
.
begin
()
t
=
transaction
.
get
()
self
.
_storage
.
tpc_begin
(
t
)
self
.
_storage
.
store
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf2
'
,
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
,
'x'
,
''
,
t
)
self
.
_storage
.
checkCurrentSerialInTransaction
(
oid
,
tid2
,
t
)
self
.
_storage
.
tpc_vote
(
t
)
self
.
_storage
.
tpc_finish
(
t
)
# non-stale read, competition after vote. The competing
# transaction most produce a tid > this transaction's tid
transaction
.
begin
()
t
=
transaction
.
get
()
self
.
_storage
.
tpc_begin
(
t
)
self
.
_storage
.
store
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf3
'
,
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
,
'x'
,
''
,
t
)
self
.
_storage
.
checkCurrentSerialInTransaction
(
oid
,
tid2
,
t
)
self
.
_storage
.
tpc_vote
(
t
)
# We'll run the competing trans in a separate thread:
import
threading
,
time
thread
=
threading
.
Thread
(
name
=
'T1'
,
target
=
self
.
_dostore
,
args
=
(
oid
,),
kwargs
=
dict
(
revid
=
tid2
))
thread
.
start
()
time
.
sleep
(.
1
)
self
.
_storage
.
tpc_finish
(
t
)
thread
.
join
()
tid3
=
self
.
_storage
.
load
(
oid
)[
1
]
self
.
assert_
(
tid3
>
self
.
_storage
.
load
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf3
'
)[
1
])
# non-stale competing trans after checkCurrentSerialInTransaction
transaction
.
begin
()
t
=
transaction
.
get
()
self
.
_storage
.
tpc_begin
(
t
)
self
.
_storage
.
store
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf4
'
,
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
0
'
,
'x'
,
''
,
t
)
self
.
_storage
.
checkCurrentSerialInTransaction
(
oid
,
tid3
,
t
)
# We'll run the competing trans in a separate thread:
thread
=
threading
.
Thread
(
name
=
'T2'
,
target
=
self
.
_dostore
,
args
=
(
oid
,),
kwargs
=
dict
(
revid
=
tid3
))
thread
.
start
()
time
.
sleep
(.
1
)
# There are 2 possibilities:
# 1. The store happens before this transaction completes,
# in which case, the vote below fails.
# 2. The store happens after this trans, in which case, the
# tid of the object is greater than this transaction's tid.
try
:
self
.
_storage
.
tpc_vote
(
t
)
except
ReadConflictError
:
thread
.
join
()
# OK :)
else
:
self
.
_storage
.
tpc_finish
(
t
)
thread
.
join
()
tid4
=
self
.
_storage
.
load
(
oid
)[
1
]
self
.
assert_
(
tid4
>
self
.
_storage
.
load
(
'
\
0
\
0
\
0
\
0
\
0
\
0
\
0
\
xf4
'
)[
1
])
src/ZODB/tests/test_storage.py
View file @
99cbe353
...
@@ -73,7 +73,8 @@ class MinimalMemoryStorage(BaseStorage, object):
...
@@ -73,7 +73,8 @@ class MinimalMemoryStorage(BaseStorage, object):
def
_clear_temp
(
self
):
def
_clear_temp
(
self
):
pass
pass
def
load
(
self
,
oid
,
version
):
def
load
(
self
,
oid
,
version
=
''
):
assert
version
==
''
self
.
_lock_acquire
()
self
.
_lock_acquire
()
try
:
try
:
assert
not
version
assert
not
version
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment