FR [ 2080217 ] Implement TrxRunnable
This commit is contained in:
parent
aabad61689
commit
b27cf2b2e5
|
@ -28,6 +28,7 @@ import java.util.Date;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.compiere.db.CConnection;
|
import org.compiere.db.CConnection;
|
||||||
import org.compiere.db.ServerConnection;
|
import org.compiere.db.ServerConnection;
|
||||||
import org.compiere.interfaces.Server;
|
import org.compiere.interfaces.Server;
|
||||||
|
@ -46,7 +47,8 @@ import org.compiere.interfaces.Server;
|
||||||
* - added rollback(boolean) and commit(boolean) [20070105]
|
* - added rollback(boolean) and commit(boolean) [20070105]
|
||||||
* - remove unnecessary use of savepoint
|
* - remove unnecessary use of savepoint
|
||||||
* - use UUID for safer transaction name generation
|
* - use UUID for safer transaction name generation
|
||||||
* @version $Id$
|
* @author Teo Sarca, http://www.arhipac.ro
|
||||||
|
* <li>FR [ 2080217 ] Implement TrxRunnable
|
||||||
*/
|
*/
|
||||||
public class Trx implements VetoableChangeListener
|
public class Trx implements VetoableChangeListener
|
||||||
{
|
{
|
||||||
|
@ -676,4 +678,80 @@ public class Trx implements VetoableChangeListener
|
||||||
return trxs;
|
return trxs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #run(String, TrxRunnable)
|
||||||
|
*/
|
||||||
|
public static void run(TrxRunnable r)
|
||||||
|
{
|
||||||
|
run(null, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute runnable object using provided transaction.
|
||||||
|
* If execution fails, database operations will be rolled back.
|
||||||
|
* <p>
|
||||||
|
* Example: <pre>
|
||||||
|
* Trx.run(null, new {@link TrxRunnable}() {
|
||||||
|
* public void run(String trxName) {
|
||||||
|
* // do something using trxName
|
||||||
|
* }
|
||||||
|
* )};
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param trxName transaction name (if null, a new transaction will be created)
|
||||||
|
* @param r runnable object
|
||||||
|
*/
|
||||||
|
public static void run(String trxName, TrxRunnable r)
|
||||||
|
{
|
||||||
|
boolean localTrx = false;
|
||||||
|
if (trxName == null) {
|
||||||
|
trxName = Trx.createTrxName("TrxRun");
|
||||||
|
localTrx = true;
|
||||||
|
}
|
||||||
|
Trx trx = Trx.get(trxName, true);
|
||||||
|
Savepoint savepoint = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!localTrx)
|
||||||
|
savepoint = trx.setSavepoint(null);
|
||||||
|
|
||||||
|
r.run(trxName);
|
||||||
|
|
||||||
|
if (localTrx)
|
||||||
|
trx.commit(true);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
// Rollback transaction
|
||||||
|
if (localTrx)
|
||||||
|
{
|
||||||
|
trx.rollback();
|
||||||
|
}
|
||||||
|
else if (savepoint != null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
trx.rollback(savepoint);
|
||||||
|
}
|
||||||
|
catch (SQLException e2) {;}
|
||||||
|
}
|
||||||
|
trx = null;
|
||||||
|
// Throw exception
|
||||||
|
if (e instanceof RuntimeException)
|
||||||
|
{
|
||||||
|
throw (RuntimeException)e;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AdempiereException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (localTrx && trx != null)
|
||||||
|
{
|
||||||
|
trx.close();
|
||||||
|
trx = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // Trx
|
} // Trx
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2008 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an object that can be ran into an transaction,
|
||||||
|
* using {@link Trx#run(TrxRunnable)} or {@link Trx#run(String, TrxRunnable)} methods.
|
||||||
|
*
|
||||||
|
* @author Teo Sarca, http://www.arhipac.ro
|
||||||
|
*/
|
||||||
|
public interface TrxRunnable
|
||||||
|
{
|
||||||
|
public void run(String trxName);
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ public class FunctionalTestSuite {
|
||||||
suite.addTestSuite(MStorageTest.class);
|
suite.addTestSuite(MStorageTest.class);
|
||||||
suite.addTestSuite(MSysConfigTest.class);
|
suite.addTestSuite(MSysConfigTest.class);
|
||||||
suite.addTestSuite(QueryTest.class);
|
suite.addTestSuite(QueryTest.class);
|
||||||
|
suite.addTestSuite(TrxTest.class);
|
||||||
suite.addTestSuite(MRefListTest.class);
|
suite.addTestSuite(MRefListTest.class);
|
||||||
suite.addTestSuite(MUOMTest.class);
|
suite.addTestSuite(MUOMTest.class);
|
||||||
//$JUnit-END$
|
//$JUnit-END$
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2008 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package test.functional;
|
||||||
|
|
||||||
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
|
import org.compiere.model.MTest;
|
||||||
|
import org.compiere.model.Query;
|
||||||
|
import org.compiere.util.Trx;
|
||||||
|
import org.compiere.util.TrxRunnable;
|
||||||
|
|
||||||
|
import test.AdempiereTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link Trx} class
|
||||||
|
* @author Teo Sarca, http://www.arhipac.ro
|
||||||
|
*/
|
||||||
|
public class TrxTest extends AdempiereTestCase {
|
||||||
|
private int m_id2 = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link Trx#run(TrxRunnable)} and {@link Trx#run(String, TrxRunnable)} methods
|
||||||
|
*/
|
||||||
|
public void testRunTrxRunnable() throws Exception
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Create test outside trx - success
|
||||||
|
m_id2 = -1;
|
||||||
|
Trx.run(new TrxRunnable() {
|
||||||
|
public void run(String trxName) {
|
||||||
|
m_id2 = createTest(trxName).get_ID();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertTestExists(m_id2, true, null);
|
||||||
|
new MTest(getCtx(), m_id2, null).deleteEx(true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create test outside trx - fail
|
||||||
|
m_id2 = -1;
|
||||||
|
try {
|
||||||
|
Trx.run(new TrxRunnable() {
|
||||||
|
public void run(String trxName) {
|
||||||
|
m_id2 = createTest(trxName).get_ID();
|
||||||
|
throw new AdempiereException("FORCE");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//
|
||||||
|
assertTrue("Should not happen because previous code is throwing exception", false);
|
||||||
|
}
|
||||||
|
catch (AdempiereException e) {
|
||||||
|
}
|
||||||
|
assertTestExists(m_id2, false, null);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create test1
|
||||||
|
String trxName = getTrxName();
|
||||||
|
MTest test1 = createTest(trxName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fail creating test2
|
||||||
|
m_id2 = -1;
|
||||||
|
try {
|
||||||
|
Trx.run(trxName, new TrxRunnable() {
|
||||||
|
public void run(String trxName) {
|
||||||
|
m_id2 = createTest(trxName).get_ID();
|
||||||
|
throw new AdempiereException("FORCE");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//
|
||||||
|
assertTrue("Should not happen because previous code is throwing exception", false);
|
||||||
|
}
|
||||||
|
catch (AdempiereException e) {
|
||||||
|
}
|
||||||
|
assertTestExists(m_id2, false, trxName);
|
||||||
|
assertTestExists(test1.get_ID(), true, trxName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Success creating test2
|
||||||
|
m_id2 = -1;
|
||||||
|
Trx.run(trxName, new TrxRunnable() {
|
||||||
|
public void run(String trxName) {
|
||||||
|
m_id2 = createTest(trxName).get_ID();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertTestExists(m_id2, true, trxName);
|
||||||
|
assertTestExists(test1.get_ID(), true, trxName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final MTest createTest(String trxName) {
|
||||||
|
MTest test = new MTest (getCtx(), "test-"+getClass(), 10);
|
||||||
|
test.set_TrxName(trxName);
|
||||||
|
test.saveEx();
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void assertTestExists(int test_id, boolean existsTarget, String trxName)
|
||||||
|
{
|
||||||
|
String whereClause = MTest.COLUMNNAME_Test_ID+"=?";
|
||||||
|
boolean exists = new Query(getCtx(), MTest.Table_Name, whereClause, trxName)
|
||||||
|
.setParameters(new Object[]{test_id})
|
||||||
|
.match();
|
||||||
|
assertEquals("Test "+test_id+" [trxName="+trxName+"] - existance issue", existsTarget, exists);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue