Integrate patches from hengsin - IDEMPIERE-3416 Implement the ability to track open DB connections (1007726/1008135)

This commit is contained in:
Carlos Ruiz 2017-06-30 15:57:15 +02:00
parent 680cf7f5a7
commit 9bfe040d9b
40 changed files with 138 additions and 4 deletions

View File

@ -221,6 +221,7 @@ public class ClientAcctProcessor extends SvrProcess
// Run every posting document in own transaction
String innerTrxName = Trx.createTrxName("CAP");
Trx innerTrx = Trx.get(innerTrxName, true);
innerTrx.setDisplayName(getClass().getName()+"_postSession");
try
{

View File

@ -104,6 +104,7 @@ public class AllocationReset extends SvrProcess
throw new AdempiereUserError(Msg.parseTranslation(getCtx(), "@Mandatory@: @C_AllocationHdr_ID@"));
m_trx = Trx.get(Trx.createTrxName("AllocReset"), true);
m_trx.setDisplayName(getClass().getName()+"_doIt");
int count = 0;
if (p_C_AllocationHdr_ID != 0)

View File

@ -208,6 +208,7 @@ public class UUIDGenerator extends SvrProcess {
Trx trx = trxName != null ? Trx.get(trxName, false) : null;
if (trx == null) {
trx = Trx.get(Trx.createTrxName(), true);
trx.setDisplayName(UUIDGenerator.class.getName()+"_updateUUID");
localTrx = true;
}
try {

View File

@ -286,6 +286,8 @@ public class DocManager {
}
Trx trx = Trx.get(trxName, true);
if (localTrxName != null)
trx.setDisplayName(DocManager.class.getName()+"_postDocument");
String error = null;
Savepoint savepoint = null;
try

View File

@ -3571,6 +3571,8 @@ public class GridTable extends AbstractTableModel
//https://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor
String trxName = m_virtual ? Trx.createTrxName("Loader") : null;
trx = trxName != null ? Trx.get(trxName, true) : null;
if (trx != null)
trx.setDisplayName(getClass().getName()+"_openResultSet");
// open Statement (closed by Loader.close)
try
{

View File

@ -163,6 +163,7 @@ public class MConversionRate extends X_C_Conversion_Rate
String trxName = Trx.createTrxName();
Trx trx = Trx.get(trxName, true);
trx.setDisplayName(MConversionRate.class.getName()+"_setRate");
Properties ctx = Env.getCtx();
MCurrency curFrom = MCurrency.get(ctx, CurFrom_ISO);
if (curFrom==null) throw new Exception("Invalid currency " + CurFrom_ISO);

View File

@ -638,6 +638,7 @@ public class MCost extends X_M_Cost
{
trxNameUsed = Trx.createTrxName("Cost");
trx = Trx.get(trxNameUsed, true);
trx.setDisplayName(MCost.class.getName()+"_create");
}
boolean success = true;
// For all Products

View File

@ -778,6 +778,7 @@ public class MLocation extends X_C_Location implements Comparator<Object>
setErrorMessage(null);
Trx trx = Trx.get(Trx.createTrxName("avt-"), true);
trx.setDisplayName(getClass().getName()+"_processOnline");
boolean ok = false;
try
{

View File

@ -283,6 +283,7 @@ public class MPackage extends X_M_Package
setErrorMessage(null);
Trx trx = Trx.get(Trx.createTrxName("spt-"), true);
trx.setDisplayName(getClass().getName()+"_processOnline");
boolean ok = false;
try
{

View File

@ -565,6 +565,7 @@ public class MPayment extends X_C_Payment
setIsApproved(approved);
Trx trx = Trx.get(Trx.createTrxName("ppt-"), true);
trx.setDisplayName(getClass().getName()+"_processOnline");
try
{

View File

@ -116,6 +116,7 @@ public final class MSetup
String adminEmail, String userEmail, boolean isSetInitialPassword)
{
log.info(clientName);
m_trx.setDisplayName(getClass().getName()+"_createClient");
m_trx.start();
// info header

View File

@ -2047,6 +2047,8 @@ public abstract class PO
l_trxname.setLength(23);
m_trxName = Trx.createTrxName(l_trxname.toString());
localTrx = Trx.get(m_trxName, true);
localTrx.setDisplayName(getClass().getName()+"_save");
localTrx.getConnection();
}
else
{
@ -3171,6 +3173,8 @@ public abstract class PO
{
localTrxName = Trx.createTrxName("POdel");
localTrx = Trx.get(localTrxName, true);
localTrx.setDisplayName(getClass().getName()+"_delete");
localTrx.getConnection();
m_trxName = localTrxName;
}
else

View File

@ -264,6 +264,7 @@ public class CreateForeignKey extends SvrProcess {
Trx trx = null;
try {
trx = Trx.get(Trx.createTrxName("CreateForeignKey"), true);
trx.setDisplayName(getClass().getName()+"_process_dropConstraint");
int rvalue = DB.executeUpdate(sql.toString(), (Object[]) null, true, trx.getTrxName());
addLog(0, null, new BigDecimal(rvalue), sql.toString());
} catch (Exception e) {
@ -302,6 +303,7 @@ public class CreateForeignKey extends SvrProcess {
Trx trx = null;
try {
trx = Trx.get(Trx.createTrxName("CreateForeignKey"), true);
trx.setDisplayName(getClass().getName()+"_process_addConstraint");
int rvalue = DB.executeUpdate(sql.toString(), (Object[]) null, true, trx.getTrxName());
addLog(0, null, new BigDecimal(rvalue), sql.toString());
if (rvalue == -1)

View File

@ -192,6 +192,7 @@ public class CreateTableIndex extends SvrProcess {
addLog(Msg.getMsg(getCtx(), "CreateTableIndexCreateTableIndex") + dbTableIndex.indexName);
Trx trx = Trx.get(Trx.createTrxName("CreateTableIndex"), true);
trx.setDisplayName(getClass().getName()+"_process_createMTableIndex");
try {
MTableIndex tableIndex = new MTableIndex(getCtx(), 0, get_TrxName());
tableIndex.setAD_Table_ID(table.getAD_Table_ID());
@ -244,6 +245,7 @@ public class CreateTableIndex extends SvrProcess {
addLog(Msg.getMsg(getCtx(), "CreateTableIndexValidateTableIndex") + tableIndex.getName());
addLog(tableIndex.getAD_TableIndex_ID(), null, null, tableIndex.toString(), tableIndex.get_Table_ID(), tableIndex.getAD_TableIndex_ID());
Trx trx = Trx.get(Trx.createTrxName("ValidateTableIndex"), true);
trx.setDisplayName(getClass().getName()+"_process_validateTableIndex");
try {
String result = TableIndexValidate.validateTableIndex(getCtx(), tableIndex, trx.getTrxName(), getProcessInfo());
addLog(result);

View File

@ -124,7 +124,10 @@ public abstract class SvrProcess implements ProcessCall
//*** Trx
boolean localTrx = m_trx == null;
if (localTrx)
{
m_trx = Trx.get(Trx.createTrxName("SvrProcess"), true);
m_trx.setDisplayName(getClass().getName()+"_startProcess");
}
//
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
ClassLoader processLoader = getClass().getClassLoader();

View File

@ -16,6 +16,8 @@
*****************************************************************************/
package org.compiere.util;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
@ -32,6 +34,7 @@ import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere;
import org.compiere.model.MSysConfig;
import org.compiere.model.PO;
/**
@ -84,6 +87,10 @@ public class Trx
private static final Trx.TrxMonitor s_monitor = new Trx.TrxMonitor();
private List<TrxEventListener> listeners = new ArrayList<TrxEventListener>();
protected Exception trace;
private String m_displayName;
public static void startTrxMonitor()
{
@ -187,6 +194,8 @@ public class Trx
}
if (!isActive())
start();
if (MSysConfig.getBooleanValue("TRACE_ALL_TRX_CONNECTION_GET", false))
trace = new Exception();
return m_connection;
} // getConnection
@ -208,6 +217,7 @@ public class Trx
{
log.log(Level.SEVERE, "connection", e);
}
trace = new Exception();
} // setConnection
/**
@ -470,6 +480,7 @@ public class Trx
}
}
m_connection = null;
trace = null;
m_active = false;
fireAfterCloseEvent();
log.config(m_trxName);
@ -538,7 +549,7 @@ public class Trx
public String toString()
{
StringBuilder sb = new StringBuilder("Trx[");
sb.append(getTrxName())
sb.append(getDisplayName())
.append(",Active=").append(isActive())
.append("]");
return sb.toString();
@ -664,6 +675,31 @@ public class Trx
}
}
public String getStrackTrace()
{
if (trace != null)
{
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
trace.printStackTrace(printWriter);
return stringWriter.getBuffer().toString();
}
else
{
return "";
}
}
public String getDisplayName()
{
return m_displayName != null ? m_displayName : m_trxName;
}
public void setDisplayName(String displayName)
{
m_displayName = displayName;
}
static class TrxMonitor implements Runnable
{
@ -681,6 +717,10 @@ public class Trx
if (since > trxs[i].getTimeout() * 1000)
{
trxs[i].log.log(Level.WARNING, "Transaction timeout. Name="+trxs[i].getTrxName() + ", timeout(sec)="+(since / 1000));
if (trxs[i].trace != null)
{
trxs[i].log.log(Level.WARNING, "Transaction timeout. Trace:\n" + trxs[i].getStrackTrace());
}
trxs[i].rollbackAndCloseOnTimeout();
}
}
@ -695,4 +735,21 @@ public class Trx
;
}
@Override
protected void finalize() throws Throwable {
if (m_connection != null && trace != null) {
final Trx me = this;
Adempiere.getThreadPoolExecutor().schedule(new Runnable() {
@Override
public void run() {
if (me.m_connection != null && me.trace != null) {
log.log(Level.WARNING, "Trx Not Close: " + me.getStrackTrace());
me.trace = null;
me.close();
}
}
}, 2, TimeUnit.SECONDS);
}
super.finalize();
}
} // Trx

View File

@ -844,6 +844,8 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
}
trx = Trx.get(get_TrxName(), true);
if (localTrx)
trx.setDisplayName(getClass().getName()+"_run");
Savepoint savepoint = null;

View File

@ -678,7 +678,10 @@ public class MWorkflow extends X_AD_Workflow
MWFProcess retValue = null;
Trx localTrx = null;
if (trxName == null)
{
localTrx = Trx.get(Trx.createTrxName("WFP"), true);
localTrx.setDisplayName(getClass().getName()+"_start");
}
try
{
retValue = new MWFProcess (this, pi, trxName != null ? trxName : localTrx.getTrxName());

View File

@ -45,6 +45,7 @@ public class PipoDictionaryService implements IDictionaryService {
PackIn packIn = null;
try {
trxName = Trx.createTrxName("PipoDS");
Trx.get(trxName, true).setDisplayName(getClass().getName()+"_merge");
packIn = new PackIn();
packIn.setPackageName(context.getBundle().getSymbolicName());

View File

@ -101,6 +101,7 @@ public abstract class AbstractActivator implements BundleActivator, ServiceTrack
}
trxName = Trx.createTrxName("ActSysTrx");
Trx.get(trxName, true).setDisplayName(getClass().getName()+"_getLockPO");
sysconfig.set_TrxName(trxName);
return sysconfig;
}

View File

@ -129,6 +129,7 @@ public class Incremental2PackActivator extends AbstractActivator {
.first();
if (firstImp == null) {
Trx trx = Trx.get(Trx.createTrxName(), true);
trx.setDisplayName(getClass().getName()+"_packIn");
try {
Env.getCtx().put("#AD_Client_ID", 0);

View File

@ -270,6 +270,7 @@ public class AlertProcessor extends AdempiereServer
Trx trx = null;
try {
trx = Trx.get(Trx.createTrxName("AP_NU"), true);
trx.setDisplayName(getClass().getName()+"_"+m_model.getName()+"_notifyUsers");
// Notice
int AD_Message_ID = 52244; /* TODO - Hardcoded message=notes */
MNote note = new MNote(getCtx(), AD_Message_ID, user_id, trx.getTrxName());

View File

@ -115,6 +115,7 @@ public class Scheduler extends AdempiereServer
try
{
m_trx = Trx.get(Trx.createTrxName("Scheduler"), true);
m_trx.setDisplayName(getClass().getName()+"_"+getModel().getName()+"_doWork");
m_summary.append(runProcess(process));
m_trx.commit(true);
}

View File

@ -957,8 +957,13 @@ public class AdempiereMonitor extends HttpServlet
{
line = new tr();
line.addElement(new th().addElement("Active Transaction "));
line.addElement(new td().addElement("Name="+trx.getTrxName()
+ ", StartTime=" + trx.getStartTime()));
td td = new td();
td.setOnClick("var newwindow=window.open('','Popup', 'width=800,height=600');newwindow.document.write('<title>" + escapeEcmaScript(trx.getDisplayName()) +"</title>"
+ "<pre>" + escapeEcmaScript(trx.getStrackTrace()) + "</pre>')");
td.addElement("Name="+trx.getDisplayName() + ", StartTime=" + trx.getStartTime());
td.setTitle("Click to see stack trace");
td.setStyle("text-decoration: underline; color: blue");
line.addElement(td);
table.addElement(line);
}
}
@ -1247,4 +1252,14 @@ public class AdempiereMonitor extends HttpServlet
return dirAccessList;
}
private static final String escapeEcmaScript(String input) {
input = input.replace("'", "\\'");
input = input.replace("\"", "\\\"");
input = input.replace("\\", "\\\\");
input = input.replace("/", "\\/");
input = input.replace("\n", "\\n");
input = input.replace("\t", "\\t");
return input;
}
} // AdempiereMonitor

View File

@ -260,6 +260,7 @@ public class FeedbackRequestWindow extends Window implements EventListener<Event
protected void saveRequest() throws IOException {
Trx trx = Trx.get(Trx.createTrxName("SaveNewRequest"), true);
trx.setDisplayName(getClass().getName()+"_saveRequest");
try {
trx.start();
MRequest request = createMRequest(trx);

View File

@ -846,6 +846,7 @@ public class WBOMDrop extends ADForm implements EventListener<Event>
{
String trxName = Trx.createTrxName("BDP");
Trx localTrx = Trx.get(trxName, true); //trx needs to be committed too
localTrx.setDisplayName(getClass().getName()+"_onSave");
try
{
if (cmd_save(localTrx))

View File

@ -634,6 +634,7 @@ public class WWFActivity extends ADForm implements EventListener<Event>
Trx trx = null;
try {
trx = Trx.get(Trx.createTrxName("FWFA"), true);
trx.setDisplayName(getClass().getName()+"_onOK");
m_activity.set_TrxName(trx.getTrxName());
if (forward != null)

View File

@ -160,6 +160,7 @@ public class ADTreeOnDropListener implements EventListener<Event> {
// *** Save changes to disk
Trx trx = Trx.get (Trx.createTrxName("ADTree"), true);
trx.setDisplayName(getClass().getName()+"_moveNode");
try
{
@SuppressWarnings("unused")

View File

@ -316,6 +316,7 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
{
String trxName = Trx.createTrxName("ChangePasswordTrx");
trx = Trx.get(trxName, true);
trx.setDisplayName(getClass().getName()+"_validateChangePassword");
for (KeyNamePair clientKNPair : m_clientKNPairs)
{

View File

@ -450,6 +450,7 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
{
String trxName = Trx.createTrxName("ResetPasswordTrx");
trx = Trx.get(trxName, true);
trx.setDisplayName(getClass().getName()+"_validateResetPassword");
for (MUser user : users)
{

View File

@ -149,6 +149,7 @@ public class GridTabDataBinder implements ValueChangeListener {
int recordId = gridTab.getKeyID(gridTab.getCurrentRow());
Trx trx = Trx.get(Trx.createTrxName(), true);
trx.setDisplayName(getClass().getName()+"_valueChange");
trx.start();
try
{

View File

@ -101,6 +101,7 @@ public class WGadgets extends Window implements EventListener<Event>{
if (panel.getButton("Ok").equals(event.getTarget()))
{
Trx trx = Trx.get(Trx.createTrxName("ManagedGadgets"), true);
trx.setDisplayName(getClass().getName()+"_onEvent_onOk");
try {
trx.start();
for(MDashboardPreference pre : dirtyList.values()) {

View File

@ -915,6 +915,7 @@ public class WLocationDialog extends Window implements EventListener<Event>
private boolean action_OK()
{
Trx trx = Trx.get(Trx.createTrxName("WLocationDialog"), true);
trx.setDisplayName(getClass().getName()+"_action_Ok");
m_location.set_TrxName(trx.getTrxName());
m_location.setAddress1(txtAddress1.getValue());
m_location.setAddress2(txtAddress2.getValue());

View File

@ -247,6 +247,7 @@ public class InOutGen extends GenForm
if (log.isLoggable(Level.INFO)) log.info("M_Warehouse_ID=" + m_M_Warehouse_ID);
String trxName = Trx.createTrxName("IOG");
Trx trx = Trx.get(trxName, true); //trx needs to be committed too
trx.setDisplayName(getClass().getName()+"_generate");
setSelectionActive(false); // prevents from being called twice
statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "InOutGenerateGen"));

View File

@ -247,6 +247,7 @@ public class InvoiceGen extends GenForm
String info = "";
String trxName = Trx.createTrxName("IVG");
Trx trx = Trx.get(trxName, true); //trx needs to be committed too
trx.setDisplayName(getClass().getName()+"_generate");
setSelectionActive(false); // prevents from being called twice
statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "InvGenerateGen"));

View File

@ -206,6 +206,7 @@ public class Match
// Create it
String innerTrxName = Trx.createTrxName("Match");
Trx innerTrx = Trx.get(innerTrxName, true);
innerTrx.setDisplayName(getClass().getName()+"_cmd_process");
try{
if (createMatchRecord(invoice, M_InOutLine_ID, Line_ID, BigDecimal.valueOf(qty), innerTrxName))

View File

@ -114,8 +114,9 @@ public class Merge
try
{
m_trx = Trx.get(Trx.createTrxName("merge"), true);
m_trx.setDisplayName(getClass().getName()+"_merge");
//
pstmt = DB.prepareStatement(sql, Trx.createTrxName());
pstmt = DB.prepareStatement(sql, m_trx.getTrxName());
pstmt.setString(1, ColumnName);
pstmt.setString(2, ColumnName);
rs = pstmt.executeQuery();

View File

@ -93,6 +93,7 @@ public class CompositeServiceImpl extends AbstractService implements CompositeSe
String trxName = Trx.createTrxName(webServiceName);
Trx trx = Trx.get(trxName, true);
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_compositeOperation");
try {
modelADService.setLocalTrxName(trxName);

View File

@ -214,6 +214,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
}
trx = Trx.get(trxName, true);
if (manageTrx)
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_setDocAction");
Map<String, Object> requestCtx = getRequestCtx();
@ -698,6 +700,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
}
trx = Trx.get(trxName, true);
if (manageTrx)
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_deleteData");
// get the PO for the tablename and record ID
MTable table = MTable.get(ctx, tableName);
@ -780,6 +784,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
}
trx = Trx.get(trxName, true);
if (manageTrx)
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_createData");
// get the PO for the tablename and record ID
@ -892,6 +898,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
manageTrx = true;
}
trx = Trx.get(trxName, true);
if (manageTrx)
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_createUpdateData");
// get the PO for the tablename and record ID
MTable table = MTable.get(ctx, tableName);
@ -1272,6 +1280,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
}
trx = Trx.get(trxName, true);
if (manageTrx)
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_updateData");
@ -1464,6 +1474,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
manageTrx = true;
}
trx = Trx.get(trxName, true);
if (manageTrx)
trx.setDisplayName(getClass().getName()+"_"+webServiceName+"_queryData");
StringBuilder sqlBuilder = new StringBuilder(role.addAccessSQL("SELECT * FROM " + tableName, tableName, true, true));

View File

@ -340,6 +340,8 @@ public class Process {
if (process.isJavaProcess() && !jasperreport)
{
Trx trx = trxName == null ? Trx.get(Trx.createTrxName("WebPrc"), true) : Trx.get(trxName, true);
if (trxName == null)
trx.setDisplayName(Process.class.getName()+"_runProcess");
try
{
processOK = process.processIt(pi, trx, false);