Hallo,
I am trying to use a pessimistic lock on a DB2/OS390 Version 7 Database.
Code:
HistoryItem hi1 = (HistoryItem)session1.load(HistoryItem.class,identifier,LockMode.UPGRADE);
It's not working.
I trace the DB2 input with the DB operator. We found that after each LockMode.UPGRADE send by hibernate (translated to: 'select ..... for update') , a close cursor follows. So the Updatelock that was set in the DB2, was removed imediately.
Hibernate 3 generates a 'select .... for update with rr'. But this is also not working because the cursor is closed imediately.
My questions are:
Who generates the close cursor statement after the select for update statement?
Who has experiences in DB2 pessimistic locking and can explain me how to lock a row in DB2.
Hibernate version: Hibernate 2.1.8
Hibernate version: Hibernate 3beta4
MappingCode:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name='de.itls.tls.hibernate.HistoryItem' dynamic-update='true' table='RL2FT0W.FTV312'>
<id name='id' column='i_R_ID' type='long' unsaved-value='0' access='field'>
<generator class='native'></generator>
</id>
<property name='text' type='string' column='i_TEXT' access='field'></property>
<property name='date' type='timestamp' column='i_DATE' access='field'></property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Session session1 = sf.openSession();
Session session2 = sf.openSession();
Transaction t1 = session1.beginTransaction();
Transaction t2 = session2.beginTransaction();
// Session 1 reads exclusiv
HistoryItem hi1 = (HistoryItem)session1.load(HistoryItem.class,identifier,LockMode.UPGRADE);
// Session 2 also tries to read exclusiv
HistoryItem hi2 = (HistoryItem)session2.load(HistoryItem.class,identifier,LockMode.UPGRADE);
// There is no lock
hi2.setText("HistoryItem 2");
session2.update(hi2);
t1.commit();
t2.commit();
Code:
package de.itls.tls.hibernate;
import de.mywms.log.LogSingleton;
import de.mywms.util.Util;
import java.util.Date;
import java.io.Serializable;
/**
* The HistoryItem is used by the process to make some notes in conjunction
* with the current time.
* A list of HistoryItems can be used to be visualized at a control station.
*
*/
public class HistoryItem
implements Serializable,
Cloneable
{
// -------------------------------------------------------------------------
private Long id ; //needed by hibernate
private int version; // needed by hibernate
/**
* Holds value of property text.
*/
private String text = "";
/**
* Holds value of property date.
*/
private Date date = new Date(System.currentTimeMillis());
// -------------------------------------------------------------------------
// properties
// -------------------------------------------------------------------------
void setVersion( int version )
{
this.version = version;
}
int getVersion()
{
return version;
}
/**
* Getter for property text.
* @return Value of property text.
*/
public String getText() {
return this.text;
}
/**
* Setter for property text.
* @param text New value of property text.
*/
public void setText(String text) {
// assertion
Util.checkNull(text);
// assignment
this.text = text;
}
// -------------------------------------------------------------------------
/**
* Getter for property date.
* @return Value of property date.
*/
public Date getDate() {
return this.date;
}
/**
* Setter for property date.
* @param date New value of property date.
*/
public void setDate(Date date) {
// assertion
if(date == null) {
throw new NullPointerException();
}
// assignment
this.date = date;
}
// -------------------------------------------------------------------------
public Object clone() {
HistoryItem hi;
try {
hi = (HistoryItem)super.clone();
hi.date = (Date)this.date.clone();
return hi;
}
catch (CloneNotSupportedException ex) {
LogSingleton.logError(ex.toString(),ex);
return null;
}
}
// -------------------------------------------------------------------------
public boolean equals(Object obj) {
if(obj == this) {
return true;
}
if(!(obj instanceof HistoryItem)) {
return false;
}
HistoryItem hi = (HistoryItem)obj;
return date.equals(hi.date) && text.equals(hi.text);
}
}
Name and version of the database you are using: DB2/OS390 Version 7[/code]