def test_conflict_del_1(self): """Check conflict detection. We modify and delete the same object in different transactions, simulating separate processes.""" txn = transaction.manager.get() foo = Foo('foo-first') self.dm.root['foo'] = foo transaction.commit() conn1 = testing.getConnection(testing.DBNAME) conn2 = testing.getConnection(testing.DBNAME) dm2 = datamanager.PJDataManager(conn2) self.assertEqual(dm2.root['foo'].name, 'foo-first') del dm2.root['foo'] dm1 = datamanager.PJDataManager(conn1) self.assertEqual(dm1.root['foo'].name, 'foo-first') dm1.root['foo'].name = 'foo-second' #Finish in order 2 - 1 with self.assertRaises(interfaces.ConflictError): transaction.commit() transaction.abort() conn2.close() conn1.close()
def setUp(test): module.setUp(test) setUpSerializers(test) g = test.globs g['conn'] = getConnection(DBNAME) g['conn_other'] = getConnection(DBNAME_OTHER) cleanDB(g['conn']) cleanDB(g['conn_other']) g['commit'] = transaction.commit g['dm'] = datamanager.PJDataManager(g['conn']) g['dm_other'] = datamanager.PJDataManager(g['conn_other']) def dumpTable(table, flush=True, isolate=False): if isolate: conn = getConnection(database=DBNAME) else: conn = g['dm']._conn with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur: try: cur.execute('SELECT * FROM ' + table) except psycopg2.ProgrammingError as err: print(err) else: pprint([dict(e) for e in cur.fetchall()]) if isolate: conn.close() g['dumpTable'] = dumpTable dmp = SimpleDataManagerProvider([g['dm'], g['dm_other']], g['dm']) zope.component.provideUtility(dmp)
def cursor(self, abort=False): transaction.abort() self.dm = datamanager.PJDataManager(self.conn) cur = self.dm.getCursor() yield cur if abort: transaction.abort() else: transaction.commit()
def test_conflict_tracebacks(self): """Verify conflict tracebacks are captured properly and reset on the next transaction.""" ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback self.assertIsNone(ctb) foo = Foo('foo-first') self.dm.root['foo'] = foo transaction.commit() conn2 = testing.getConnection(testing.DBNAME) dm2 = datamanager.PJDataManager(conn2) del dm2.root['foo'] conn1 = testing.getConnection(testing.DBNAME) dm1 = datamanager.PJDataManager(conn1) dm1.root['foo'].name = 'foo-second' ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback self.assertIsNone(ctb) # Finish in order 2 - 1 with self.assertRaises(interfaces.ConflictError): transaction.commit() # verify by length that we have the full traceback ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback self.assertIsNotNone(ctb) # Make all work self.assertTrue(len(ctb) > 20) self.assertIn('Beacon:', ctb[-1]) transaction.abort() # start another transaction and verify the traceback # is reset datamanager.PJDataManager(conn2) ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback self.assertIsNone(ctb) conn2.close() conn1.close()
def insertPeople(self, options): if options.reload: connroot = getConnection() with connroot.cursor() as cur: cur.execute('END;') cur.execute('DROP DATABASE IF EXISTS performance;') cur.execute('CREATE DATABASE performance;') connroot.commit() datamanager.PJ_AUTO_CREATE_TABLES = False if LOG_SQL: testing.log_sql_to_file('/tmp/pjpersist.table.log') conn = getConnection('performance') dm = datamanager.PJDataManager(conn) dm.create_tables(('people', 'person', 'address')) dm.root._init_table() #dm._new_obj_cache._ensure_db_objects() # this speeds up slow_read around TWICE #with conn.cursor() as cur: # cur.execute('END;') # cur.execute( # "CREATE INDEX data_name ON person ((data->>('name')));") dm.root['people'] = people = People() transaction.commit() def insert(): for idx in xrange(options.size): klass = (self.personKlass if (MULTIPLE_CLASSES and idx % 2) else self.person2Klass) people[None] = klass('Mr Number %.5i' % idx, random.randint(0, 100)) # Profile inserts t1 = time.time() if PROFILE: cProfile.runctx('insert()', globals(), locals(), filename=self.profile_output + '_insert') else: insert() transaction.commit() t2 = time.time() self.printResult('Insert', t1, t2, options.size) else: people = dm.root['people'] return people
def test_conflict_del_2(self): """Check conflict detection. We modify and delete the same object in different transactions, simulating separate processes.""" foo = Foo('foo-first') self.dm.root['foo'] = foo transaction.commit() conn1 = testing.getConnection(testing.DBNAME) dm1 = datamanager.PJDataManager(conn1) self.assertEqual(dm1.root['foo'].name, 'foo-first') dm1.root['foo'].name = 'foo-second' conn2 = testing.getConnection(testing.DBNAME) dm2 = datamanager.PJDataManager(conn2) self.assertEqual(dm2.root['foo'].name, 'foo-first') del dm2.root['foo'] #Finish in order 1 - 2 # well, try to... dm1.tpc_finish will block until dm2 is done @testing.run_in_thread def background_commit(): with self.assertRaises(interfaces.ConflictError): dm1.commit(None) dm2.commit(None) transaction.abort() conn2.close() conn1.close()
def get(self, database): # Make sure the dict containing the local data managers exists. if not hatattr(LOCAL, 'dms'): LOCAL.dms = {} # Get the data manager, if it exists. try: return LOCAL.dms[database] except KeyError: pass # Create a new pool, if necessary. if database not in self.pools: self.pools[database] = psycopg2.pool.PersistentConnectionPool( database=database, user=self.user, password=self.password, host=self.host, port=self.port) # Create a new data manager and return it. LOCAL.dms[database] = datamanager.PJDataManager( self.pools[database].getconn()) return LOCAL.dms[database]
def setUp(self): super(DirtyTestCase, self).setUp() # get rid of the previous transaction transaction.abort() tpc_patch = mock.patch( "pjpersist.datamanager.PJ_TWO_PHASE_COMMIT_ENABLED", True) no_prep_patch = mock.patch( "pjpersist.datamanager." "CALL_TPC_PREPARE_ON_NO_WRITE_TRANSACTION", False) log_patch = mock.patch( "pjpersist.datamanager.LOG_READ_WRITE_TRANSACTION", True) self.patches = [tpc_patch, no_prep_patch, log_patch] for p in self.patches: p.start() # First PJDataManager instantiation creates tables, what makes the dm # dirty, which we want to avoid here. self.conn = testing.getConnection(testing.DBNAME) self.dm = datamanager.PJDataManager(self.conn)
def getPeople(self, options): conn = getConnection('performance') dm = datamanager.PJDataManager(conn) people = dm.root['people'] return people
def setUp(self): setUpSerializers(self) self.conn = getConnection(DBNAME) cleanDB(self.conn) self.dm = datamanager.PJDataManager(self.conn)