I have an application written by a 3rd party which uses Java/Tomcat talking to an Oracle 12c (12.2.0.1) DB. In its logs it reports "Error inserting into table" but provides no details. In talking with the author's support staff they indicate it is old code and they have no way to give more detail. They say the application is better supported with MSSQL which we do not support in our shop.
I would like to see what the insert statement going to the Oracle DB looks like, but haven't been able to find it in v$sqltext. As an alternative, I was hoping to find a tool like fiddler to view the outbound traffic on port 1521.
Is there specific tool that would allow trapping this traffic which is not encrypted so I can see the "query" sent and the response coming back from the Oracle DB?
A general sniffer may work, but they generally get a lot of extraneous traffic and require a fair amount of mucking about to find what you want.
Note:
As I mentioned in the comments I am not a Tomcat/Java person. I think I found where the classpath is set. Given the windows batch file below, is the "driver" that needs to be replaced bcprov-jdk16-138.jar?
set PROJLIB=..\..
set JAVA_HOME=%PROJLIB%\jdk\
set libDIR=%PROJLIB%\appserver\webapps\receiver\WEB-INF\lib
set consoleDIR=%PROJLIB%\bin\lib
set endorsedLibDir=%PROJLIB%\appserver\endorsed
set CPATH= %consoleDIR%\console.jar;%libDIR%\ebxml.jar;%libDIR%\commons-io-1.1.jar;%libDIR%\bcprov-jdk16-138.jar;%libDIR%\xercesImpl.jar
set CLASSPATH=%CPATH%
set PATH=%JAVA_HOME%\bin;%SystemRoot%;%SystemRoot%\system32
Additional Notes:
The above file is called setenv.bat.
Regarding trying to capture the SQL from the database, the application is not a windows app, it is an app which accepts data from the network and writes it to the DB. This makes knowing precisely when to start and stop monitoring difficult. It seems to be connected for a very short period. It does seem to be able to read data, but not insert.
Assuming that you are using the Oracle JDBC driver and that you have the ability to replace the JDBC driver in some environment in order to debug the problem, Oracle provides versions of the JDBC driver that can be configured to log the SQL statements that are executed.
An alternative would be to create a servererror trigger in the database that logs the SQL statements that fail. I believe that would require that the SQL statement that is failing is well-formed which isn't guaranteed if the third party app is encountering an error dynamically assembling the statement. If the statement never lands in v$sql that may indicate that it isn't well-formed but it's worth a try.
If you're licensed to use the AWR/ ASH tables, you could also try querying dba_hist_active_sess_history. Oracle samples the active sessions every second. If the failing statement happens to be caught in the sampling, you'd see it there. If this is a typical OLTP application doing single-row inserts, you may need to run through a lot of samples in order to catch an active session with that statement but that may be reasonable.
The simples approach is, if you can localize your database session (using gv$session selecting your connection USERNAME).
Get the SID and SERIAL# of the connection and activate the 10046 trace using the following statement. (substutite SID for session_id and SERIAL# for serial_num)
EXEC DBMS_MONITOR.session_trace_enable(session_id =>271, serial_num=>46473, binds=>TRUE);
Note that you need permissions for both querying gv$session and executing DBMS_MONITOR so DBA access is required to grant them to your user.
Than check the trace file on the database server in folder trace, the trace file has a name such as xe_m005_1336.trc
Grep for the table name, you schould see someting like this I simulated for failed insert on the table my_table
=====================
PARSING IN CURSOR #854854488 len=38 dep=0 uid=104 oct=2 lid=104 tim=380974114197 hv=1259660490 ad='7ff08904d88' sqlid='1ttgvst5j9t6a'
insert into my_table(col1) values(:1 )
END OF STMT
PARSE #854854488:c=0,e=495,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=380974114195
=====================
PARSE ERROR #854854488:len=39 dep=0 uid=104 oct=2 lid=104 tim=380974117361 err=904
insert into my_table(col1) values(:1 )
Note that this is example of an exception
java.sql.SQLSyntaxErrorException: ORA-00904: "COL1": invalid identifier
so the statement fails with an PARSE ERROR
If the insert fails due to some constraint vialotation, you will see such sequence
=====================
PARSING IN CURSOR #715594288 len=37 dep=0 uid=104 oct=2 lid=104 tim=382407621534 hv=3290870806 ad='7ff0032e238' sqlid='17t3q0v22dd0q'
insert into my_table(col) values(:1 )
END OF STMT
PARSE #715594288:c=0,e=245,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=382407621532
=====================
The cursor id is #715594288so check with this id further in the trace file
BINDS #715594288:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=01 csi=873 siz=24 off=0
kxsbbbfp=2aa71a00 bln=22 avl=02 flg=05
value=7
=====================
Here you see the bind variables passed in the insert, it was the value = 7 that caused the failure.
EXEC #715594288:c=0,e=4614,p=0,cr=7,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=382407626259
ERROR #715594288:err=2290 tim=382407626283
The statement failed in the execution with exception such as
java.sql.SQLIntegrityConstraintViolationException: ORA-02290: check constraint (XXXX.SYS_C0012357) violated
Check the documentation for further details
If you have db access via sqldeveloper....
Go to reports tab, then drill down through data dictionary, database administration, sessions, and finally sessions.
In that view, look for your app's active module(s) and look at the Active SQL tab.
One of them should have your insert statement....
This might help as well...
https://docs.oracle.com/cd/E17781_01/server.112/e18804/monitoring.htm#ADMQS252
The ultimate approach is to trace the JDBC connection on the client. Please find the full documentation here
In the first step you must get the logging JDBC driver on the CLASSPATH. The logging driver has a suggix _g in the name, e.g. ojdbc8_g.jar if you use ojdbc8.jar
The driver can be found in the Oracle installation in the folder jdbc/lib/
Further you must define a properties file say jdbcLogging.properties with following content
.level=SEVERE
oracle.jdbc.level=ALL
oracle.jdbc.handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
Finally when you run the Java application you must define two properties
java -Doracle.jdbc.Trace=true -Djava.util.logging.config.file=jdbcLogging.properties ...
This will produce a trace file om the error output where you can find the executed statements.
Example
INFO: DRCP Enabled: false
Mar 23, 2021 10:40:31 PM oracle.jdbc.driver.OracleStatement logSQL
CONFIG: BAB2F1 SQL: insert into my_table(col1) values(?)
What I ended up doing was downloading WireShark, a sniffer, and monitored the TCP/IP packets.
I want to check the number of active open connections in mysql database using java and close it.
I tried using query only
SHOW STATUS LIKE 'threads_connected';
With this can anyone tell me how to find and close the connection. I know when a database connection is established we need to close it immediately but for some other requirement i want to know active connections list and delete that list.
Any idea please suggest
I pulled aout the strings used bei HeidiSQL
First for getting a list with active connections(Processes):
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, LEFT(INFO, 51200) AS Info FROM information_schema.PROCESSLIST
The for deleting a processes:
KILL {The ID of the Process};
It would probably be enough to SELECT only the ID of the Process but with that query you get all Information needed.
I am developing a game with client-server, client of this game can be from Flash Web, J2ME or Android Mobile. Every day there are 300-400 users play this game. I am faced with headache problem, and I spent many days to resolve it, but hopeless ...When I run this app on server Linux (8 core processors): after one day this app consumes CPU about 100% (one core is used 100%), and the second day it consumes CPU 300%, and next day 500%... about 4-5 days, I must restart this app to prevent it not be crashed. In my project, each player I use a thread to transfer data (between client and server) and manipulate with DB, beside it, I also use many threads to manage play game of players or log information, these threads also manipulate with DataBase when necessary. Every time player or thread wants to get some information or saves something into DataBase, I create a connection for each query and close this connection after finish the query, it looks like this:
getSomething(int id) {
...
String sql = "SELECT * FROM mail WHERE id = ?";
connection = ConnectionManager.getDbConnection();
pstmt = connection.prepareStatement(sql);
....
while (rs.next()) {
...
}
connection.close();
}
It means if 400 users login or save something at the same time, 400 connections will be created to get or save data for each of user, and 400 connections will be released after finish query. I not sure this strategy is good ... or it can be the reason of my problem ...
In my log, sometime there are log with "too many connections..." it make me doubt about closing connection in my app, and this can cause CPU consumes over 100%, more connections are not released, more CPU consumes...
Now I think I should use JDBC Connection Pool to manage connections from clients, and hope it can resolve my problem ... but I am not sure, it can be not work ...
So, if you have any idea, please suggest to me, thank you so much!
I have few SQL Server Agent Jobs running in my project. The jobs run perfectly as scheduled, no issues.
But now I need to be able to start these jobs from the front end (Like on a click of button or so).
How can I do it ?
Do these jobs behave just like a functions ?
You can do this with any db connector I've tried--here are a couple examples...
Using CallableStatement:
Connection rConn = //however you get your connection...
CallableStatement cs = rConn.prepareCall("EXEC dbo.sp_start_job N'your job name'");
boolean checkvar = cs.execute();
Alternatively, if you use a jdbc template:
jdbcTemp = //however you get your template...
jdbcTemp.update("EXEC msdb.dbo.sp_start_job N'" + procName + "'");
Also, you will likely need to adjust the permissions of the msdb in order for this to work. Your account needs to either be a sysadmin or have the SQLAgentOperatorRole role. To set this in SQL Server Management, go to Security under your db engine, expand logins, right click on the account you will use and select properties. Under Server Roles you can grant sysadmin, or under User Mapping check msdb, then select TargetServersRole and SQLAgentOperatorRole from the list below.
hth
you can call it by using the sp_startjob proc
example
EXEC msdb.dbo.sp_start_job N'MyJobName';
Does anyone know how to evict or kill open connections (in use or not it doesn't matter) if the number of connections is above of a fixed limit (e.g. maxActive) Currently I'm using DBCP from Apache under a Sun One 6.1.
Thanks in advance!,
ALTER SYSTEM KILL SESSION 'nnn,mmmm' can kill sessions (with nnn being the SID and mmmm the SERIAL#). You can look at v$session seconds_in_wait and with an event of 'SQL*Net message from client' for sessions that haven't been doing anything in a while. That event basically says "I'm waiting for a client to tell me what to do next."
Also make sure the session doesn't have an open transaction
select sid, serial# from v$session
where event = 'SQL*Net message from client'
and saddr not in (select ses_addr from v$transaction)
order by seconds_in_wait desc;
It's an ugly solution though.