Commit 844fd710 authored by Jim Fulton's avatar Jim Fulton

Implement IStorageTransactionMetaDataExtensionBytes and use in in Connection

parent 76fe6271
......@@ -141,7 +141,7 @@ setup(name="ZODB",
'persistent >= 4.2.0',
'BTrees >= 4.2.0',
'ZConfig',
'transaction >= 1.6.1',
'transaction >= 2.0.0',
'six',
'zc.lockfile',
'zope.interface',
......
......@@ -49,6 +49,7 @@ from ZODB import utils
import six
from .mvccadapter import HistoricalStorageAdapter
from ._compat import dumps, loads, _protocol
from . import valuedoc
......@@ -458,15 +459,22 @@ class Connection(ExportImport, object):
def tpc_begin(self, transaction):
"""Begin commit of a transaction, starting the two-phase commit."""
self._modified = []
meta_data = TransactionMetaData(
transaction.user,
transaction.description,
transaction.extended_info)
transaction.set_data(self, meta_data)
# _creating is a list of oids of new objects, which is used to
# remove them from the cache if a transaction aborts.
self._creating.clear()
self._normal_storage.tpc_begin(transaction)
self._normal_storage.tpc_begin(meta_data)
def commit(self, transaction):
"""Commit changes to an object"""
transaction = transaction.data(self)
if self._savepoint_storage is not None:
# We first checkpoint the current changes to the savepoint
......@@ -611,6 +619,8 @@ class Connection(ExportImport, object):
obj._p_serial = s
def tpc_abort(self, transaction):
transaction = transaction.data(self)
if self._import:
self._import = None
......@@ -667,6 +677,9 @@ class Connection(ExportImport, object):
vote = self._storage.tpc_vote
except AttributeError:
return
transaction = transaction.data(self)
try:
s = vote(transaction)
except ReadConflictError as v:
......@@ -683,6 +696,8 @@ class Connection(ExportImport, object):
def tpc_finish(self, transaction):
"""Indicate confirmation that the transaction is done.
"""
transaction = transaction.data(self)
serial = self._storage.tpc_finish(transaction)
assert type(serial) is bytes, repr(serial)
for oid_iterator in self._modified, self._creating:
......@@ -1270,3 +1285,54 @@ large_record_size option of the ZODB.DB constructor (or the
large-record-size option in a configuration file) to specify a larger
size.
"""
class TransactionMetaData:
def __init__(self, user=u'', description=u'', extension=b''):
self.user = user
self.description = description
if isinstance(extension, bytes):
self.extension_bytes = extension
else:
self.extension = extension
@property
def user(self):
return self.__user
@user.setter
def user(self, user):
if not isinstance(user, bytes):
user = user.encode('utf-8')
self.__user = user
@property
def description(self):
return self.__description
@description.setter
def description(self, description):
if not isinstance(description, bytes):
description = description.encode('utf-8')
self.__description = description
@property
def extension(self):
return self.__extension
@extension.setter
def extension(self, v):
self.__extension = v
self.__extension_bytes = dumps(v, _protocol) if v else b''
_extension = extension
@property
def extension_bytes(self):
return self.__extension_bytes
@extension_bytes.setter
def extension_bytes(self, v):
d = loads(v) if v else {}
self.__extension_bytes = v if d else b''
self.__extension = d
......@@ -21,6 +21,8 @@ import sys
import unittest
import transaction
from transaction import Transaction
import ZODB.tests.util
from ZODB.config import databaseFromString
from ZODB.utils import p64, u64, z64
......@@ -52,7 +54,7 @@ class ConnectionDotAdd(ZODB.tests.util.TestCase):
self.db = StubDatabase()
self.datamgr = Connection(self.db)
self.datamgr.open()
self.transaction = StubTransaction()
self.transaction = Transaction()
def test_add(self):
from ZODB.POSException import InvalidObjectReference
......@@ -700,7 +702,6 @@ def doctest_readCurrent():
>>> bad = set()
>>> def checkCurrentSerialInTransaction(oid, serial, trans):
... six.print_('checkCurrentSerialInTransaction', repr(oid))
... if trans != transaction.get(): print('oops')
... if oid in bad:
... raise ReadConflictError(oid=oid)
......@@ -1192,9 +1193,6 @@ class EstimatedSizeTests(ZODB.tests.util.TestCase):
class StubObject(Persistent):
pass
class StubTransaction:
pass
class ErrorOnGetstateException(Exception):
pass
......
......@@ -84,10 +84,10 @@ class MVCCTests:
storage = c1._storage
t = transaction.Transaction()
t.description = 'isolation test 1'
storage.tpc_begin(t)
c1.tpc_begin(t)
c1.commit(t)
storage.tpc_vote(t)
storage.tpc_finish(t)
storage.tpc_vote(t.data(c1))
storage.tpc_finish(t.data(c1))
# The second connection will now load root['alpha'], but due to
# MVCC, it should continue to see the old state.
......@@ -110,10 +110,10 @@ class MVCCTests:
storage = c1._storage
t = transaction.Transaction()
t.description = 'isolation test 2'
storage.tpc_begin(t)
c1.tpc_begin(t)
c1.commit(t)
storage.tpc_vote(t)
storage.tpc_finish(t)
storage.tpc_vote(t.data(c1))
storage.tpc_finish(t.data(c1))
# The second connection will now load root[3], but due to MVCC,
# it should continue to see the old state.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment