Opened 10 years ago

Closed 10 years ago

#798 closed (fixed)

Emptying trashcan error as proxy is associated with two open sessions

Reported by: olle Owned by: olle
Milestone: Proteios SE 2.18.0 Keywords:
Cc:

Description

When one tries to empty the trashcan, sometimes an error occurs because a proxy is associated with two open sessions. The full error message is "BaseException: illegally attempted to associate a proxy with two open Sessions".

Change History (5)

comment:1 Changed 10 years ago by olle

Status: newassigned

Ticket accepted.

comment:2 Changed 10 years ago by olle

Traceability note:

  • Deletion of items was introduced in Ticket #46 (Permanent removal of items), where class/file action/write/EmptyTrash.java was added in change set [1454].
  • Deletion of items as a job was introduced in Ticket #620 (Empty trashcan as job), where class/file plugins/EmptyTrashPlugin.java in plugin/ was added in change set [3451].

comment:3 Changed 10 years ago by olle

Problem discussion:

The same error has occurred when performing protein assembly a second time, and previously generated proteins are removed at the start. The original code used one DbControl object dc to iterate over the hits, and another dc3 to delete them:

DbControl dc3 = sc.newDbControl();
for (Iterator<Hit> iter = hitQuery.iterate(dc); iter.hasNext();)
{
  Hit hit = iter.next();
  dc3.deleteItem(hit);
  counter++;
}
dc3.commit();

This problem seems to be solved by simply using same DbControl object dc3 to iterate over the hits, as to delete them (change set [4404] for Ticket #745 "Protein assembly for all samples at once"):

DbControl dc3 = sc.newDbControl();
for (Iterator<Hit> iter = hitQuery.iterate(dc3); iter.hasNext();)
{
  Hit hit = iter.next();
  dc3.deleteItem(hit);
  counter++;
}
dc3.commit();

In the case of emptying the trash, the situation is a little more intricate. Two DbControl objects dc and dc2 are used:

ItemResultList<?> itemList = query.list(dc);
...
for (int i=0; i < itemList.size(); i++)
{
  ...
  try
  {
    itemList.get(i).getDbControl().detachItem(itemList.get(i));
    dc2 = newDbControl();
    dc2.reattachItem(itemList.get(i));
    dc2.deleteItem(itemList.get(i));
    dc2.commit();
  }
  catch (Exception e)
  {
    log.debug(...);
    ...
  }
  dc2.close();
  ...
}

Here the line with itemList.get(i).getDbControl().detachItem(itemList.get(i)) should release the item in question from the first DbControl object dc, and it seems to work in most cases, but obviously not in all. When emptying the trash, it is not desired to use the same DbControl object to generate the item list, as for deleting items, since one wants to be able to use the original list in the final stage, where one checks what, if any, items could not be deleted.

Detachment and reattachment of items from/to DbControl objects are known to be somewhat shaky. Instead of reattaching an item to a new DbControl object, it is normally safer to let the latter get the item from its database id. The following enhancements are therefore proposed:

  • DbControl object dc is used to create an ItemResultList<?> itemResultList from a database query. This is in turn used to create a List<BasicItem<?>> itemList of the items of interest.
  • DbControl object dc is closed, and List<BasicItem<?>> itemList is used to loop over the items.
  • For each item, DbControl object dc2 is created and used to get a new instance of the item from its database id. DbControl object dc2 is then used to delete the latter item, the change is committed, and DbControl object dc2 is closed.
  • DbControl object dc is created again, and used to generate a list of items still in the database, that is checked against the List<BasicItem<?>> itemList of items to delete.
Last edited 10 years ago by olle (previous) (diff)

comment:4 Changed 10 years ago by olle

(In [4412]) Refs #798. Refs #620. Refs #46. Classes/files action/write/EmptyTrash.java in client/servlet/ and plugins/EmptyTrashPlugin.java in plugin/ have been updated to hopefully avoid errors due to a proxy being associated with two open sessions. The updated routine has the following main steps:

  • DbControl object dc is used to create an ItemResultList<?> itemResultList from a database query. This is in turn used to create a List<BasicItem<?>> itemList of the items of interest.
  • DbControl object dc is closed, and List<BasicItem<?>> itemList is used to loop over the items.
  • For each item, DbControl object dc2 is created and used to get a new instance of the item from its database id. DbControl object dc2 is then used to delete the latter item, the change is committed, and DbControl object dc2 is closed.
  • DbControl object dc is created again, and used to generate a list of items still in the database, that is checked against the List<BasicItem<?>> itemList of items to delete.

comment:5 Changed 10 years ago by olle

Resolution: fixed
Status: assignedclosed

Ticket closed as the added update hopefully will decrease the risk of errors due to a proxy being associated with two open sessions.

Note: See TracTickets for help on using tickets.