예제 #1
0
    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()
예제 #2
0
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)
예제 #3
0
 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()
예제 #4
0
    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()
예제 #5
0
    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
예제 #6
0
    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()
예제 #7
0
파일: pool.py 프로젝트: sjustas/pjpersist
 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]
예제 #8
0
    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)
예제 #9
0
    def getPeople(self, options):
        conn = getConnection('performance')

        dm = datamanager.PJDataManager(conn)
        people = dm.root['people']
        return people
예제 #10
0
 def setUp(self):
     setUpSerializers(self)
     self.conn = getConnection(DBNAME)
     cleanDB(self.conn)
     self.dm = datamanager.PJDataManager(self.conn)