[ 1886013 ] MSequence.getNextId should be executed outside of trx

This commit is contained in:
Heng Sin Low 2008-02-04 03:38:19 +00:00
parent cb8ecc26b3
commit b67b5a1268
1 changed files with 64 additions and 69 deletions

View File

@ -49,12 +49,17 @@ public class MSequence extends X_AD_Sequence
/** Log Level for Next ID Call */ /** Log Level for Next ID Call */
private static final Level LOGLEVEL = Level.ALL; private static final Level LOGLEVEL = Level.ALL;
public static synchronized int getNextID (int AD_Client_ID, String TableName)
{
return getNextID(AD_Client_ID, TableName, null);
}
/** /**
*
* Get next number for Key column = 0 is Error. * Get next number for Key column = 0 is Error.
* @param AD_Client_ID client * @param AD_Client_ID client
* @param TableName table name * @param TableName table name
* @param trxName optional Transaction Name * @param trxName deprecated.
* @return next no or (-1=not found, -2=error) * @return next no or (-1=not found, -2=error)
*/ */
public static synchronized int getNextID (int AD_Client_ID, String TableName, String trxName) public static synchronized int getNextID (int AD_Client_ID, String TableName, String trxName)
@ -70,7 +75,8 @@ public class MSequence extends X_AD_Sequence
{ {
if (server != null) if (server != null)
{ // See ServerBean { // See ServerBean
int id = server.getNextID(AD_Client_ID, TableName, trxName); // hengsin: don't execute getNextID in tranaction to fix performance and locking issue
int id = server.getNextID(AD_Client_ID, TableName, null);
s_log.finest("server => " + id); s_log.finest("server => " + id);
if (id < 0) if (id < 0)
throw new DBException("No NextID"); throw new DBException("No NextID");
@ -96,7 +102,7 @@ public class MSequence extends X_AD_Sequence
s_log.log(LOGLEVEL, TableName + " - AdempiereSys=" + adempiereSys + " [" + trxName + "]"); s_log.log(LOGLEVEL, TableName + " - AdempiereSys=" + adempiereSys + " [" + trxName + "]");
//begin vpj-cd e-evolution 09/02/2005 PostgreSQL //begin vpj-cd e-evolution 09/02/2005 PostgreSQL
String selectSQL = null; String selectSQL = null;
if (DB.isOracle() == false) if (DB.isOracle() == false || DB.isRemoteObjects())
{ {
selectSQL = "SELECT CurrentNext, CurrentNextSys, IncrementNo, AD_Sequence_ID " selectSQL = "SELECT CurrentNext, CurrentNextSys, IncrementNo, AD_Sequence_ID "
+ "FROM AD_Sequence " + "FROM AD_Sequence "
@ -116,17 +122,19 @@ public class MSequence extends X_AD_Sequence
USE_PROCEDURE = true; USE_PROCEDURE = true;
} }
Trx trx = trxName == null ? null : Trx.get(trxName, true); //hengsin: executing getNextID in transaction create huge performance and locking issue
//Trx trx = trxName == null ? null : Trx.get(trxName, true);
Connection conn = null; Connection conn = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
boolean autocommit = false; boolean autocommit = false;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
try try
{ {
if (trx != null) //if (trx != null)
conn = trx.getConnection(); //conn = trx.getConnection();
else //else
conn = DB.getConnectionID(); conn = DB.getConnectionID();
// Error // Error
if (conn == null) if (conn == null)
@ -139,7 +147,7 @@ public class MSequence extends X_AD_Sequence
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
pstmt.setString(1, TableName); pstmt.setString(1, TableName);
// //
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (CLogMgt.isLevelFinest()) if (CLogMgt.isLevelFinest())
s_log.finest("AC=" + conn.getAutoCommit() + ", RO=" + conn.isReadOnly() s_log.finest("AC=" + conn.getAutoCommit() + ", RO=" + conn.isReadOnly()
+ " - Isolation=" + conn.getTransactionIsolation() + "(" + Connection.TRANSACTION_READ_COMMITTED + " - Isolation=" + conn.getTransactionIsolation() + "(" + Connection.TRANSACTION_READ_COMMITTED
@ -168,11 +176,14 @@ public class MSequence extends X_AD_Sequence
if (retValue > 0) { if (retValue > 0) {
PreparedStatement updateSQL; PreparedStatement updateSQL;
updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNextSys = ? + 1 WHERE AD_Sequence_ID = ?"); updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNextSys = ? + 1 WHERE AD_Sequence_ID = ?");
try {
updateSQL.setInt(1, retValue); updateSQL.setInt(1, retValue);
updateSQL.setInt(2, AD_Sequence_ID); updateSQL.setInt(2, AD_Sequence_ID);
updateSQL.executeUpdate(); updateSQL.executeUpdate();
} finally {
updateSQL.close(); updateSQL.close();
} }
}
gotFromHTTP = true; gotFromHTTP = true;
} }
@ -188,11 +199,14 @@ public class MSequence extends X_AD_Sequence
if (retValue > 0) { if (retValue > 0) {
PreparedStatement updateSQL; PreparedStatement updateSQL;
updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNext = GREATEST(CurrentNext, ? + 1) WHERE AD_Sequence_ID = ?"); updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNext = GREATEST(CurrentNext, ? + 1) WHERE AD_Sequence_ID = ?");
try {
updateSQL.setInt(1, retValue); updateSQL.setInt(1, retValue);
updateSQL.setInt(2, AD_Sequence_ID); updateSQL.setInt(2, AD_Sequence_ID);
updateSQL.executeUpdate(); updateSQL.executeUpdate();
} finally {
updateSQL.close(); updateSQL.close();
} }
}
gotFromHTTP = true; gotFromHTTP = true;
} }
@ -217,26 +231,22 @@ public class MSequence extends X_AD_Sequence
.prepareStatement("UPDATE AD_Sequence SET CurrentNext = CurrentNext + ? WHERE AD_Sequence_ID = ?"); .prepareStatement("UPDATE AD_Sequence SET CurrentNext = CurrentNext + ? WHERE AD_Sequence_ID = ?");
retValue = rs.getInt(1); retValue = rs.getInt(1);
} }
try {
updateSQL.setInt(1, incrementNo); updateSQL.setInt(1, incrementNo);
updateSQL.setInt(2, AD_Sequence_ID); updateSQL.setInt(2, AD_Sequence_ID);
updateSQL.executeUpdate(); updateSQL.executeUpdate();
} finally {
updateSQL.close(); updateSQL.close();
} }
} }
}
if (trx == null) //if (trx == null)
conn.commit(); conn.commit();
} }
else else
s_log.severe ("No record found - " + TableName); s_log.severe ("No record found - " + TableName);
rs.close();
pstmt.close();
pstmt = null;
conn.setAutoCommit(autocommit); //jz set back
//
if (trx == null && conn != null)
conn.close();
conn = null;
// //
break; // EXIT break; // EXIT
} }
@ -254,24 +264,27 @@ public class MSequence extends X_AD_Sequence
{ {
} }
} }
Thread.yield(); // give it time finally
}
// Finish
try
{ {
if (pstmt != null) DB.close(rs, pstmt);
pstmt.close();
pstmt = null; pstmt = null;
// if (conn != null) rs = null;
// conn.close(); if (conn != null)
{
try {
conn.setAutoCommit(autocommit); //jz set back
} catch (SQLException e) {}
try {
conn.close();
} catch (SQLException e) {}
conn = null; conn = null;
} }
catch (Exception e)
{
s_log.log(Level.SEVERE, "Finish", e);
pstmt = null;
} }
s_log.finest (retValue + " - Table=" + TableName + " [" + trx + "]"); Thread.yield(); // give it time
}
//s_log.finest (retValue + " - Table=" + TableName + " [" + trx + "]");
return retValue; return retValue;
} // getNextID } // getNextID
@ -433,7 +446,7 @@ public class MSequence extends X_AD_Sequence
String selectSQL = null; String selectSQL = null;
if (DB.isOracle() == false) if (DB.isOracle() == false || DB.isRemoteObjects())
{ {
if (isStartNewYear) { if (isStartNewYear) {
selectSQL = "SELECT y.CurrentNext, s.IncrementNo, s.CurrentNextSys, s.Prefix, s.Suffix, s.AD_Sequence_ID " selectSQL = "SELECT y.CurrentNext, s.IncrementNo, s.CurrentNextSys, s.Prefix, s.Suffix, s.AD_Sequence_ID "
@ -804,7 +817,7 @@ public class MSequence extends X_AD_Sequence
} }
String selectSQL = null; String selectSQL = null;
if (DB.isOracle() == false) if (DB.isOracle() == false || DB.isRemoteObjects())
{ {
if (isStartNewYear) if (isStartNewYear)
{ {
@ -1217,24 +1230,6 @@ public class MSequence extends X_AD_Sequence
return retValue; return retValue;
} // getNextNo } // getNextNo
/**
* Get next DocumentNo
* @return document no
*/
public String getDocumentNo()
{
// create DocumentNo
StringBuffer doc = new StringBuffer();
String prefix = getPrefix();
if (prefix != null && prefix.length() > 0)
doc.append(prefix);
doc.append(getNextID());
String suffix = getSuffix();
if (suffix != null && suffix.length() > 0)
doc.append(suffix);
return doc.toString();
} // getDocumentNo
/** /**
* Validate Table Sequence Values * Validate Table Sequence Values
* @return true if updated * @return true if updated