Workspace already in transaction mode — two separate edit sessions

738
3
Jump to solution
06-14-2022 01:05 PM
IanTodd
New Contributor II

I'm creating an ArcMap toolbar that will be used to update a feature layer and related table in an SDE. As of now, I'm creating two edit sessions: one for the layer and one for the table — preferably, I could do it in one edit session. However, I get an error that the workspace is already in transaction when I try to insert a row into the related table.

The onClick method kicks off the attempt. It successfully runs the first start method (in Tiles), but fails with a transaction mode error for the second start method (in RelatedTable).

def editor(sub_function):
    def _runner(*args, **kwargs):
        edit = arcpy.da.Editor(Tiles.root())
        result = None
        try:
            edit.startEditing(False, True)
            edit.startOperation()
            result = sub_function(*args, **kwargs)
            success = True
        except Exception as e:
            print(traceback.format_exc())
            success = False
        finally:
            if edit.isEditing:
                edit.stopOperation()
                edit.stopEditing(success)
            del edit
            return result
    return _runner
    def onClick(self):
        result, tile_id, row = Tiles.start()
        if result == Tiles.NO_ERROR:
            result = RelatedTable.start(tile_id)
            if result:
                KeyMaster.tile_start()
            else:
                Tiles.revert_start(row)
        elif result == Tiles.SELECTION_COUNT_INVALID:
            send_message("Only one tile can be selected.", 'Error')
        elif result == Tiles.SELECTION_VALUE_INVALID:
            send_message('The tile must be "checked out" in your name before it can be started.', 'Error')
    @classmethod
    def start(cls):
        @editor
        def updater():
            fields = [EditFields.user, EditFields.status, FieldNames.id]
            tile_id, row = None, None
            with arcpy.da.UpdateCursor(Tiles.get(), fields) as cursor:
                for row in cursor:
                    if (row[0] == FieldValues.USERNAME) or KeyMaster.is_unlocked():
                        row[0] = FieldValues.USERNAME
                        row[1] = FieldValues.STARTED
                        tile_id = row[2]
                        cursor.updateRow(row)
            return tile_id, row

        fids = cls.fid_set()
        if len(fids) != 1:
            return Tiles.SELECTION_COUNT_INVALID, None, None
        tile_id, row = updater()
        if tile_id is not None:
            return Tiles.NO_ERROR, tile_id, row
        else:
            return Tiles.SELECTION_VALUE_INVALID, None, None
    @classmethod
    def start(cls, tile_id):
        @editor
        def updater():
            fields = [RelatedTable._userField,
                    RelatedTable._startField,
                    RelatedTable._idField,
                    RelatedTable._typeField]
            with arcpy.da.InsertCursor(RelatedTable.get(), fields) as cursor:
                row = [FieldValues.USERNAME,
                        datetime.datetime.now(),
                        tile_id,
                        EditFields.get_type()]
                RelatedTable.set_fid(cursor.insertRow(row))
                RelatedTable.set_id(tile_id)
            return True
        success = updater()
        if success:
            return Tiles.NO_ERROR
        else:
            return Tiles.SELECTION_COUNT_INVALID
Tags (3)
0 Kudos
1 Solution

Accepted Solutions
IanTodd
New Contributor II

Turns out that while the tiles feature class was set to versioned, the related table was not. Changing the related table to versioned fixed the error. Still would have been nice to have an error message that might have pointed toward this being the problem...

View solution in original post

0 Kudos
3 Replies
RhettZufelt
MVP Frequent Contributor

I suspect it is because you are trying to loop through an insertCursor.  Just set the cursor to a variable, then insertRow(value).

This tech support article and this post should give you good enough example to see if that is the issue.

R_

0 Kudos
IanTodd
New Contributor II

InsertCursor is not being used in a loop. As the code's written, the InsertCursor is called in a completely different function well after UpdateCursor has fallen out of scope. I did try setting InsertCursor as a variable, but I'm getting the same problem.

IanTodd
New Contributor II

Turns out that while the tiles feature class was set to versioned, the related table was not. Changing the related table to versioned fixed the error. Still would have been nice to have an error message that might have pointed toward this being the problem...

0 Kudos