Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Tryton
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
External wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Tryton
Tryton
Commits
aa0589b57da0
"README.md" did not exist on "312774dff867445898c3580a92fda5af813755ad"
Commit
aa0589b57da0
authored
8 years ago
by
Nicolas Évrard
Browse files
Options
Downloads
Patches
Plain Diff
Support Two-Phase Commit protocol in Transaction
issue3553 review23741003
parent
74f22b3b9e48
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
CHANGELOG
+1
-0
1 addition, 0 deletions
CHANGELOG
doc/ref/transaction.rst
+12
-0
12 additions, 0 deletions
doc/ref/transaction.rst
trytond/tests/test_transaction.py
+46
-0
46 additions, 0 deletions
trytond/tests/test_transaction.py
trytond/transaction.py
+59
-19
59 additions, 19 deletions
trytond/transaction.py
with
118 additions
and
19 deletions
CHANGELOG
+
1
−
0
View file @
aa0589b5
* Support Two-Phase Commit in Transaction
* Allow Report to generate text plain, XML, HTML and XHTML
* Add workflow graph on ir.model
* Add context model on ir.action.act_window
...
...
This diff is collapsed.
Click to expand it.
doc/ref/transaction.rst
+
12
−
0
View file @
aa0589b5
...
...
@@ -82,5 +82,15 @@
Create a new transaction with the same database, user and context as the
original transaction and adds it to the stack of transactions.
.. method:: Transaction.join(datamanager)
Register in the transaction a data manager conforming to the `Two-Phase
Commit protocol`_. More information on how to implement such data manager
is available at the `Zope documentation`_.
This method returns the registered datamanager. It could be a different yet
equivalent (in term of python equality) datamanager than the one passed to the
method.
.. _`context manager`: http://docs.python.org/reference/datamodel.html#context-managers
.. _`PEP-0249`: https://www.python.org/dev/peps/pep-0249/
...
...
@@ -85,2 +95,4 @@
.. _`context manager`: http://docs.python.org/reference/datamodel.html#context-managers
.. _`PEP-0249`: https://www.python.org/dev/peps/pep-0249/
.. _`Two-Phase Commit protocol`: https://en.wikipedia.org/wiki/Two-phase_commit_protocol
.. _`Zope documentation`: http://zodb.readthedocs.org/en/latest/transactions.html#the-two-phase-commit-protocol-in-practice
This diff is collapsed.
Click to expand it.
trytond/tests/test_transaction.py
+
46
−
0
View file @
aa0589b5
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import
unittest
from
mock
import
Mock
from
trytond.tests.test_tryton
import
DB_NAME
,
USER
,
CONTEXT
,
install_module
from
trytond.transaction
import
Transaction
...
...
@@ -75,6 +76,51 @@
self
.
assertIs
(
Transaction
(),
new_transaction
)
self
.
assertIs
(
Transaction
(),
transaction
)
def
test_two_phase_commit
(
self
):
# A successful transaction
dm
=
Mock
()
with
Transaction
().
start
(
DB_NAME
,
USER
,
context
=
CONTEXT
)
\
as
transaction
:
transaction
.
join
(
dm
)
dm
.
tpc_begin
.
assert_called_once_with
(
transaction
)
dm
.
commit
.
assert_called_once_with
(
transaction
)
dm
.
tpc_vote
.
assert_called_once_with
(
transaction
)
dm
.
tpc_abort
.
not_called
()
dm
.
tpc_finish
.
assert_called_once_with
(
transaction
)
# Failing in the datamanager
dm
.
reset_mock
()
dm
.
tpc_vote
.
side_effect
=
ValueError
(
'
Failing the datamanager
'
)
try
:
with
Transaction
().
start
(
DB_NAME
,
USER
,
context
=
CONTEXT
)
\
as
transaction
:
transaction
.
join
(
dm
)
except
ValueError
:
pass
dm
.
tpc_begin
.
assert_called_once_with
(
transaction
)
dm
.
commit
.
assert_called_once_with
(
transaction
)
dm
.
tpc_vote
.
assert_called_once_with
(
transaction
)
dm
.
tpc_abort
.
assert_called_once_with
(
transaction
)
dm
.
tpc_finish
.
assert_not_called
()
# Failing in tryton
dm
.
reset_mock
()
try
:
with
Transaction
().
start
(
DB_NAME
,
USER
,
context
=
CONTEXT
)
\
as
transaction
:
transaction
.
join
(
dm
)
raise
ValueError
(
'
Failing in tryton
'
)
except
ValueError
:
pass
dm
.
tpc_begin
.
assert_not_called
()
dm
.
commit
.
assert_not_called
()
dm
.
tpc_vote
.
assert_not_called
()
dm
.
tpc_abort
.
assert_called_once_with
(
transaction
)
dm
.
tpc_finish
.
assert_not_called
()
def
suite
():
return
unittest
.
TestLoader
().
loadTestsFromTestCase
(
TransactionTestCase
)
This diff is collapsed.
Click to expand it.
trytond/transaction.py
+
59
−
19
View file @
aa0589b5
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import
logging
from
threading
import
local
from
sql
import
Flavor
from
trytond
import
backend
from
trytond.config
import
config
...
...
@@ -3,9 +4,11 @@
from
threading
import
local
from
sql
import
Flavor
from
trytond
import
backend
from
trytond.config
import
config
logger
=
logging
.
getLogger
(
__name__
)
class
_AttributeManager
(
object
):
'''
...
...
@@ -95,6 +98,7 @@
self
.
delete
=
{}
self
.
timestamp
=
{}
self
.
counter
=
0
self
.
_datamanagers
=
[]
return
self
def
__enter__
(
self
):
...
...
@@ -102,24 +106,31 @@
def
__exit__
(
self
,
type
,
value
,
traceback
):
transactions
=
self
.
_local
.
transactions
if
transactions
.
count
(
self
)
==
1
:
if
type
is
None
and
not
self
.
readonly
:
self
.
commit
()
try
:
self
.
rollback
()
self
.
database
.
put_connection
(
self
.
connection
,
self
.
close
)
finally
:
self
.
database
=
None
self
.
readonly
=
False
self
.
connection
=
None
self
.
close
=
None
self
.
user
=
None
self
.
context
=
None
self
.
create_records
=
None
self
.
delete_records
=
None
self
.
delete
=
None
self
.
timestamp
=
None
current_instance
=
transactions
.
pop
()
try
:
if
transactions
.
count
(
self
)
==
1
:
try
:
try
:
if
type
is
None
and
not
self
.
readonly
:
self
.
commit
()
else
:
self
.
rollback
()
finally
:
self
.
database
.
put_connection
(
self
.
connection
,
self
.
close
)
finally
:
self
.
database
=
None
self
.
readonly
=
False
self
.
connection
=
None
self
.
close
=
None
self
.
user
=
None
self
.
context
=
None
self
.
create_records
=
None
self
.
delete_records
=
None
self
.
delete
=
None
self
.
timestamp
=
None
self
.
_datamanagers
=
[]
finally
:
current_instance
=
transactions
.
pop
()
assert
current_instance
is
self
,
transactions
def
set_context
(
self
,
context
=
None
,
**
kwargs
):
...
...
@@ -162,8 +173,27 @@
autocommit
=
autocommit
)
def
commit
(
self
):
self
.
connection
.
commit
()
try
:
if
self
.
_datamanagers
:
for
datamanager
in
self
.
_datamanagers
:
datamanager
.
tpc_begin
(
self
)
for
datamanager
in
self
.
_datamanagers
:
datamanager
.
commit
(
self
)
for
datamanager
in
self
.
_datamanagers
:
datamanager
.
tpc_vote
(
self
)
self
.
connection
.
commit
()
except
:
self
.
rollback
()
raise
else
:
try
:
for
datamanager
in
self
.
_datamanagers
:
datamanager
.
tpc_finish
(
self
)
except
:
logger
.
critical
(
'
A datamanager raised an exception in
'
'
tpc_finish, the data might be inconsistant
'
,
exc_info
=
True
)
def
rollback
(
self
):
for
cache
in
self
.
cache
.
itervalues
():
cache
.
clear
()
...
...
@@ -166,6 +196,8 @@
def
rollback
(
self
):
for
cache
in
self
.
cache
.
itervalues
():
cache
.
clear
()
for
datamanager
in
self
.
_datamanagers
:
datamanager
.
tpc_abort
(
self
)
self
.
connection
.
rollback
()
...
...
@@ -170,5 +202,13 @@
self
.
connection
.
rollback
()
def
join
(
self
,
datamanager
):
try
:
idx
=
self
.
_datamanagers
.
index
(
datamanager
)
return
self
.
_datamanagers
[
idx
]
except
ValueError
:
self
.
_datamanagers
.
append
(
datamanager
)
return
datamanager
@property
def
language
(
self
):
def
get_language
():
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment