IDEMPIERE-5509 Implement readonly query with using Trx (#1599)
This commit is contained in:
parent
8cf16e9fbd
commit
8ab72bcba2
|
@ -45,6 +45,17 @@ public class PreparedStatementProxy extends StatementProxy {
|
||||||
init();
|
init();
|
||||||
} // PreparedStatementProxy
|
} // PreparedStatementProxy
|
||||||
|
|
||||||
|
public PreparedStatementProxy(int resultSetType, int resultSetConcurrency,
|
||||||
|
String sql0, Connection connection) {
|
||||||
|
if (sql0 == null || sql0.length() == 0)
|
||||||
|
throw new IllegalArgumentException("sql required");
|
||||||
|
|
||||||
|
p_vo = new CStatementVO(resultSetType, resultSetConcurrency, DB
|
||||||
|
.getDatabase().convertStatement(sql0));
|
||||||
|
|
||||||
|
init(connection);
|
||||||
|
} // PreparedStatementProxy
|
||||||
|
|
||||||
public PreparedStatementProxy(CStatementVO vo)
|
public PreparedStatementProxy(CStatementVO vo)
|
||||||
{
|
{
|
||||||
super(vo);
|
super(vo);
|
||||||
|
@ -74,6 +85,19 @@ public class PreparedStatementProxy extends StatementProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the prepared statement wrapper object
|
||||||
|
*/
|
||||||
|
protected void init(Connection connection) {
|
||||||
|
try {
|
||||||
|
p_stmt = connection.prepareStatement(p_vo.getSql(), p_vo
|
||||||
|
.getResultSetType(), p_vo.getResultSetConcurrency());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, p_vo.getSql(), e);
|
||||||
|
throw new DBException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RowSet getRowSet()
|
protected RowSet getRowSet()
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
package org.compiere.db;
|
package org.compiere.db;
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
import org.compiere.util.CCallableStatement;
|
import org.compiere.util.CCallableStatement;
|
||||||
import org.compiere.util.CPreparedStatement;
|
import org.compiere.util.CPreparedStatement;
|
||||||
|
@ -56,6 +57,21 @@ public class ProxyFactory {
|
||||||
new PreparedStatementProxy(resultSetType, resultSetConcurrency, sql, trxName));
|
new PreparedStatementProxy(resultSetType, resultSetConcurrency, sql, trxName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param resultSetType
|
||||||
|
* @param resultSetConcurrency
|
||||||
|
* @param sql
|
||||||
|
* @param trxName
|
||||||
|
* @return CPreparedStatement proxy
|
||||||
|
*/
|
||||||
|
public static CPreparedStatement newCPreparedStatement(int resultSetType,
|
||||||
|
int resultSetConcurrency, String sql, Connection connection) {
|
||||||
|
return (CPreparedStatement)Proxy.newProxyInstance(CPreparedStatement.class.getClassLoader(),
|
||||||
|
new Class[]{CPreparedStatement.class},
|
||||||
|
new PreparedStatementProxy(resultSetType, resultSetConcurrency, sql, connection));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param resultSetType
|
* @param resultSetType
|
||||||
|
|
|
@ -711,6 +711,17 @@ public final class DB
|
||||||
return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, trxName);
|
return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, trxName);
|
||||||
} // prepareStatement
|
} // prepareStatement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Statement
|
||||||
|
* @param sql
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return Prepared Statement
|
||||||
|
*/
|
||||||
|
public static CPreparedStatement prepareStatement (Connection connection, String sql)
|
||||||
|
{
|
||||||
|
return prepareStatement(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
||||||
|
} // prepareStatement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare Statement.
|
* Prepare Statement.
|
||||||
* @param sql
|
* @param sql
|
||||||
|
@ -742,6 +753,23 @@ public final class DB
|
||||||
return ProxyFactory.newCPreparedStatement(resultSetType, resultSetConcurrency, sql, trxName);
|
return ProxyFactory.newCPreparedStatement(resultSetType, resultSetConcurrency, sql, trxName);
|
||||||
} // prepareStatement
|
} // prepareStatement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Statement.
|
||||||
|
* @param sql sql statement
|
||||||
|
* @param resultSetType - ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE
|
||||||
|
* @param resultSetConcurrency - ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE
|
||||||
|
* @param trxName transaction name
|
||||||
|
* @return Prepared Statement r/o or r/w depending on concur
|
||||||
|
*/
|
||||||
|
public static CPreparedStatement prepareStatement(Connection connection, String sql,
|
||||||
|
int resultSetType, int resultSetConcurrency)
|
||||||
|
{
|
||||||
|
if (sql == null || sql.length() == 0)
|
||||||
|
throw new IllegalArgumentException("No SQL");
|
||||||
|
//
|
||||||
|
return ProxyFactory.newCPreparedStatement(resultSetType, resultSetConcurrency, sql, connection);
|
||||||
|
} // prepareStatement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Read Only Statement
|
* Create Read Only Statement
|
||||||
* @return Statement
|
* @return Statement
|
||||||
|
@ -1242,19 +1270,21 @@ public final class DB
|
||||||
int retValue = -1;
|
int retValue = -1;
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Trx trx = null;
|
Connection conn = null;
|
||||||
if (trxName == null)
|
if (trxName == null)
|
||||||
{
|
conn = DB.createConnection(true, Connection.TRANSACTION_READ_COMMITTED);
|
||||||
trxName = Trx.createTrxName("getSQLValueEx");
|
|
||||||
trx = Trx.get(trxName, true);
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.getConnection().setReadOnly(true);
|
conn.setAutoCommit(false);
|
||||||
|
conn.setReadOnly(true);
|
||||||
}
|
}
|
||||||
pstmt = prepareStatement(sql, trxName);
|
|
||||||
|
if (conn != null)
|
||||||
|
pstmt = prepareStatement(conn, sql);
|
||||||
|
else
|
||||||
|
pstmt = prepareStatement(sql, trxName);
|
||||||
setParameters(pstmt, params);
|
setParameters(pstmt, params);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
if (rs.next())
|
if (rs.next())
|
||||||
|
@ -1264,9 +1294,13 @@ public final class DB
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.rollback();
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new DBException(e, sql);
|
throw new DBException(e, sql);
|
||||||
}
|
}
|
||||||
|
@ -1274,14 +1308,32 @@ public final class DB
|
||||||
{
|
{
|
||||||
close(rs, pstmt);
|
close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.close();
|
closeAndResetReadonlyConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void closeAndResetReadonlyConnection(Connection conn) {
|
||||||
|
try {
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.setReadOnly(false);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get String Value from sql
|
* Get String Value from sql
|
||||||
* @param trxName optional transaction name
|
* @param trxName optional transaction name
|
||||||
|
@ -1341,19 +1393,21 @@ public final class DB
|
||||||
String retValue = null;
|
String retValue = null;
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Trx trx = null;
|
Connection conn = null;
|
||||||
if (trxName == null)
|
if (trxName == null)
|
||||||
{
|
conn = DB.createConnection(true, Connection.TRANSACTION_READ_COMMITTED);
|
||||||
trxName = Trx.createTrxName("getSQLValueEx");
|
|
||||||
trx = Trx.get(trxName, true);
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.getConnection().setReadOnly(true);
|
conn.setAutoCommit(false);
|
||||||
|
conn.setReadOnly(true);
|
||||||
}
|
}
|
||||||
pstmt = prepareStatement(sql, trxName);
|
|
||||||
|
if (conn != null)
|
||||||
|
pstmt = prepareStatement(conn, sql);
|
||||||
|
else
|
||||||
|
pstmt = prepareStatement(sql, trxName);
|
||||||
setParameters(pstmt, params);
|
setParameters(pstmt, params);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
if (rs.next())
|
if (rs.next())
|
||||||
|
@ -1363,9 +1417,13 @@ public final class DB
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.rollback();
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new DBException(e, sql);
|
throw new DBException(e, sql);
|
||||||
}
|
}
|
||||||
|
@ -1373,9 +1431,9 @@ public final class DB
|
||||||
{
|
{
|
||||||
close(rs, pstmt);
|
close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.close();
|
closeAndResetReadonlyConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
|
@ -1440,19 +1498,21 @@ public final class DB
|
||||||
BigDecimal retValue = null;
|
BigDecimal retValue = null;
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Trx trx = null;
|
Connection conn = null;
|
||||||
if (trxName == null)
|
if (trxName == null)
|
||||||
{
|
conn = DB.createConnection(true, Connection.TRANSACTION_READ_COMMITTED);
|
||||||
trxName = Trx.createTrxName("getSQLValueEx");
|
|
||||||
trx = Trx.get(trxName, true);
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.getConnection().setReadOnly(true);
|
conn.setAutoCommit(false);
|
||||||
|
conn.setReadOnly(true);
|
||||||
}
|
}
|
||||||
pstmt = prepareStatement(sql, trxName);
|
|
||||||
|
if (conn != null)
|
||||||
|
pstmt = prepareStatement(conn, sql);
|
||||||
|
else
|
||||||
|
pstmt = prepareStatement(sql, trxName);
|
||||||
setParameters(pstmt, params);
|
setParameters(pstmt, params);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
if (rs.next())
|
if (rs.next())
|
||||||
|
@ -1462,9 +1522,13 @@ public final class DB
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.rollback();
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new DBException(e, sql);
|
throw new DBException(e, sql);
|
||||||
}
|
}
|
||||||
|
@ -1472,9 +1536,9 @@ public final class DB
|
||||||
{
|
{
|
||||||
close(rs, pstmt);
|
close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.close();
|
closeAndResetReadonlyConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
|
@ -1540,19 +1604,21 @@ public final class DB
|
||||||
Timestamp retValue = null;
|
Timestamp retValue = null;
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Trx trx = null;
|
Connection conn = null;
|
||||||
if (trxName == null)
|
if (trxName == null)
|
||||||
{
|
conn = DB.createConnection(true, Connection.TRANSACTION_READ_COMMITTED);
|
||||||
trxName = Trx.createTrxName("getSQLValueEx");
|
|
||||||
trx = Trx.get(trxName, true);
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.getConnection().setReadOnly(true);
|
conn.setAutoCommit(false);
|
||||||
|
conn.setReadOnly(true);
|
||||||
}
|
}
|
||||||
pstmt = prepareStatement(sql, trxName);
|
|
||||||
|
if (conn != null)
|
||||||
|
pstmt = prepareStatement(conn, sql);
|
||||||
|
else
|
||||||
|
pstmt = prepareStatement(sql, trxName);
|
||||||
setParameters(pstmt, params);
|
setParameters(pstmt, params);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
if (rs.next())
|
if (rs.next())
|
||||||
|
@ -1562,9 +1628,13 @@ public final class DB
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.rollback();
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new DBException(e, sql);
|
throw new DBException(e, sql);
|
||||||
}
|
}
|
||||||
|
@ -1572,9 +1642,9 @@ public final class DB
|
||||||
{
|
{
|
||||||
close(rs, pstmt);
|
close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.close();
|
closeAndResetReadonlyConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
|
@ -2455,19 +2525,21 @@ public final class DB
|
||||||
List<Object> retValue = new ArrayList<Object>();
|
List<Object> retValue = new ArrayList<Object>();
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Trx trx = null;
|
Connection conn = null;
|
||||||
if (trxName == null)
|
if (trxName == null)
|
||||||
{
|
conn = DB.createConnection(true, Connection.TRANSACTION_READ_COMMITTED);
|
||||||
trxName = Trx.createTrxName("getSQLValueObjectsEx");
|
|
||||||
trx = Trx.get(trxName, true);
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.getConnection().setReadOnly(true);
|
conn.setAutoCommit(false);
|
||||||
|
conn.setReadOnly(true);
|
||||||
}
|
}
|
||||||
pstmt = prepareStatement(sql, trxName);
|
|
||||||
|
if (conn != null)
|
||||||
|
pstmt = prepareStatement(conn, sql);
|
||||||
|
else
|
||||||
|
pstmt = prepareStatement(sql, trxName);
|
||||||
setParameters(pstmt, params);
|
setParameters(pstmt, params);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
ResultSetMetaData rsmd = rs.getMetaData();
|
ResultSetMetaData rsmd = rs.getMetaData();
|
||||||
|
@ -2485,9 +2557,13 @@ public final class DB
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.rollback();
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new DBException(e, sql);
|
throw new DBException(e, sql);
|
||||||
}
|
}
|
||||||
|
@ -2495,9 +2571,9 @@ public final class DB
|
||||||
{
|
{
|
||||||
close(rs, pstmt);
|
close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.close();
|
closeAndResetReadonlyConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
|
@ -2516,19 +2592,21 @@ public final class DB
|
||||||
List<List<Object>> rowsArray = new ArrayList<List<Object>>();
|
List<List<Object>> rowsArray = new ArrayList<List<Object>>();
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
Trx trx = null;
|
Connection conn = null;
|
||||||
if (trxName == null)
|
if (trxName == null)
|
||||||
{
|
conn = DB.createConnection(true, Connection.TRANSACTION_READ_COMMITTED);
|
||||||
trxName = Trx.createTrxName("getSQLArrayObjectsEx");
|
|
||||||
trx = Trx.get(trxName, true);
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.getConnection().setReadOnly(true);
|
conn.setAutoCommit(false);
|
||||||
|
conn.setReadOnly(true);
|
||||||
}
|
}
|
||||||
pstmt = prepareStatement(sql, trxName);
|
|
||||||
|
if (conn != null)
|
||||||
|
pstmt = prepareStatement(conn, sql);
|
||||||
|
else
|
||||||
|
pstmt = prepareStatement(sql, trxName);
|
||||||
setParameters(pstmt, params);
|
setParameters(pstmt, params);
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
ResultSetMetaData rsmd = rs.getMetaData();
|
ResultSetMetaData rsmd = rs.getMetaData();
|
||||||
|
@ -2546,9 +2624,13 @@ public final class DB
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{
|
{
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.rollback();
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new DBException(e, sql);
|
throw new DBException(e, sql);
|
||||||
}
|
}
|
||||||
|
@ -2556,9 +2638,9 @@ public final class DB
|
||||||
{
|
{
|
||||||
close(rs, pstmt);
|
close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
if (trx != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
trx.close();
|
closeAndResetReadonlyConnection(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rowsArray.size() == 0)
|
if (rowsArray.size() == 0)
|
||||||
|
|
Loading…
Reference in New Issue