#22 Transactional Problem

open
nobody
None
5
2014-08-17
2006-04-03
Anonymous
No

Hi,

I've been using c3p0 with Hibernate and Ingres for the
last couple of weeks and all was going well until i
tried some concurrency tests. I'm interested in
'transactions-per-second' as this is an important
aspect of my project. When i got up to about 30
transactional (persiting the object though Hibernate so
no choice) inserts down one connection, spread evenly
over a second, i started to get the follow two exceptions:

1. ca.gcf.util.SqlEx: line 1, The dynamically defined
statement 'jdbc_stmt_0_2' not found.
Perhaps a PREPARE or DESCRIBE wasn't successful.

2. org.hibernate.transaction.JDBCTransaction] - JDBC
commit failed
ca.gcf.util.SqlEx: Invalid transaction state for
requested operation.

I build a test class to try and expose the problem more
clearly (which i've pasted in below), during which i
found that if a switched my connection to the Hibernate
in build pool all was fine, swtiching to the bare
Ingres implementations was notably worse by the way.

I worked out a better way of achieving the goal of this
part of the project, but i thought i'd share what i'd
found with you all the same in the hope for a detailed
explanation of the problems i encounted (want to be
sure they won't pop up again further down the line!).

I would appreciate any advise/critique on the method in
the class below.

Cheers

Tom

/**
*
* @hibernate.class table="ConcurrentFinders"
*/

public class ConcurrentThresholdFinder implements Runnable{

//Instance vars
String aField = "Value";
String anotherField = "SimilarValue";

int createdNum = 0;
int ID;

//static vars

static SessionFactory hiberFact = null;

//c3p0 tech
static String connectionUrl = null;//please fill
static String userName = null;//please fill
static String password = null;//please fill

static Connection conn = null;

public ConcurrentThresholdFinder(int createdNum){
this.createdNum = createdNum;
}

public void run(){
System.out.println(createdNum+" is attempting
persistence");
try{
Session sess = null;

if(conn == null){
sess = hiberFact.openSession();
}else{
sess = hiberFact.openSession(conn);
}

long time = System.currentTimeMillis();
sess.beginTransaction();

sess.save(this);

sess.getTransaction().commit();

time = System.currentTimeMillis() - time;

System.out.println(createdNum+" persisted
successfully, in "+time);
}catch(Exception e){
StringWriter stackTrace = new StringWriter();
e.printStackTrace(new PrintWriter(stackTrace));
System.err.println(createdNum+" encountered a "+e+".
Trace -- "+stackTrace);
}
}

public static void main (String[] args) throws
PropertyVetoException, SQLException{

boolean usec3p0Connection = true;
boolean useIngresConn = false;

//Create Hibernate Factory
Configuration config = new
Configuration().configure(new
File("HibernateConfigs/hibernate.cfg.xml"));

File filo = new
File("XdocGend/meta/experiments/hibernate/concurrency/ConcurrentThresholdFinder.hbm.xml");

config.addFile(filo);

ConcurrentThresholdFinder.hiberFact =
config.buildSessionFactory();

if(usec3p0Connection){
//Create c3p0 pool to try different connection types
ComboPooledDataSource cpds = new
ComboPooledDataSource();
cpds.setDriverClass("ca.ingres.jdbc.IngresDriver");
//loads the jdbc driver
cpds.setJdbcUrl( connectionUrl );
cpds.setUser(userName);

cpds.setPassword(password);

//the settings below are optional -- c3p0 can work
with defaults
//See InsertionThresholdFinder in Experiments to
explore these settings
cpds.setInitialPoolSize(1);//does nuting
cpds.setMinPoolSize(1);

cpds.setAcquireIncrement(5); //does nuting
cpds.setMaxPoolSize(2);

cpds.setNumHelperThreads(2);

ConcurrentThresholdFinder.conn = cpds.getConnection();
}

if(useIngresConn){
IngresDataSource ids = new IngresDataSource();

ids.setServerName("test8");
ids.setPortName("II7");
ids.setUser(userName);
ids.setPassword(password);
ids.setDatabaseName("test1");
ids.setDbmsUser(userName);
ids.setDbmsPassword(password);

ConcurrentThresholdFinder.conn = ids.getConnection();
}

//Loop configuration vars

int numOfTrans = 40;
int spreadOver = 1000;

int delayTime = spreadOver/numOfTrans;

//loop vars
Thread thread;
Object delay = new Object();

for(int i=1;i<=numOfTrans;i++){
thread = new Thread(new ConcurrentThresholdFinder(i));
thread.start();

synchronized(delay){
try {
delay.wait(delayTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

//Hibernate tagged gets

/**
* @hibernate.id generator-class="increment" column="ID"
*/
public int getID() {
return ID;
}

/**
* @hibernate.property
*/
public String getAField() {
return aField;
}

/**
* @hibernate.property
*/
public String getAnotherField() {
return anotherField;
}

/**
* @hibernate.property
*/
public int getCreatedNum() {
return createdNum;
}
//The Sets
public void setAField(String field) {
aField = field;
}
public void setAnotherField(String anotherField) {
this.anotherField = anotherField;
}
public void setCreatedNum(int createdNum) {
this.createdNum = createdNum;
}
public void setID(int id) {
ID = id;
}
}

Discussion