Actually i am facing a problem calling a stored procedure and making some changes in the database in the same transaction. What i am doing is that i insert some data from en EJB (3.0) using jpql into an oracle database and than i call a stored procedure with a native jpa query to make some processing with the fresh data. But the problem is that the PL/SQL function doesn't see changes unless i commit the transaction and than i make the call what i don't want to do because i want to keep all changes in the same transaction. So the question is : is there any way to insert my data, call the pl/sql function and commit everything after that (or eventually roll back all changes) ?
thank you for your help
Make sure to call entityManager.flush() before executing your stored procedure. Else, the persistence context might still have pending changes in memory. Flushing makes sure all the pending changes are written to the database.
If that doesn't work, then it means that the stored proc uses a different transaction than the one used by JPA.
Related
In fact, the PostgreSQL documentation states that all interactions with the database are performed within a transaction.
PostgreSQL actually treats every SQL statement as being executed within a transaction. If you do not issue a BEGIN command, then each individual statement has an implicit BEGIN and (if successful) COMMIT wrapped around it. A group of statements surrounded by BEGIN and COMMIT is sometimes called a transaction block.
Given this, even something like SELECT name FROM users will initiate a COMMIT. Is there a way to avoid this? In other words—is there a means of looking at the data in a table without issuing a COMMIT or a ROLLBACK? In the case of statements whose sole purpose is to fetch some data, it seems like superfluous overhead.
I read this and recognize that having SELECT statements be within a transaction is important; it allows one to take a snapshot of the data and thus remain consistent about what rows are where and what data they contain—but, then, is there a way to end a transaction without the overhead of COMMIT or ROLLBACK (in the case where neither is actually necessary)?
I recognize that having SELECT statements be within a transaction is important; it allows one to take a snapshot of the data and thus remain consistent
Good.
but, then, is there a way to end a transaction without the overhead of COMMIT or ROLLBACK?
Committing a transaction that did only read data does not have any overhead. All you need to do is drop the transaction handle and the resources allocated for it.
The "implicit COMMIT" just means that the transaction is getting closed/exited/completed - with or without actually writing anything. You cannot have the transaction without ending it.
I am a new for Postgres. Currently I hit a situation, I need to retrieve a record from DB/table, then update this record with some changes, then retrieve the updated record again to return to customer, these 3 operations are executed sequentially.
After I run the above 3 steps, sometimes it seems the record has not been updated. But in fact the record has been updated, I suspect when I retrieve the record, Postgres return a cached data rather than fresh data. Actually all DB operations are correct, I guess just Postgres returns cached records.
I am wondering if there is any mechanism to flush my updated data immediately?
Another question is, I am wondering which one is a good practice:
Update a record (actually write to DB), then immediately retrieve the record from DB, both operations are using statement to operate.
Update a record (actually write to DB), then don't retrieve record from DB, because we know updated data, we just use these data to return to customer. However, the record might fail to write DB.
Any ideas for the above?
Some programming languages do db calls asynchronously, meaning that your code is moving on to the next db operation without waiting for the first to finish. So, it could be as simple as using your language's "await" keyword to make sure you are waiting for your db to finish the "update record" before trying to read it again.
If you are writing raw sql or you know it is not an issue with making several db call asynchronously, you could try writing your update and read calls as a single transaction.
See https://www.postgresql.org/docs/14/tutorial-transactions.html if you're unfamiliar with writing transactions.
As per my understanding flush() method of JPA's entitymanager will sync the data available in persistence context with Database in a single DB network call. Thus it avoids multiple DB calls when somebody trying to persist large amount of records. Why can't I consider this as a batch equivalent (I know flush() may not be implemented for that purpose) of JDBC batch insert ? Because, JDBC batch insert also work with the same idea that it make only single DB call for all the statements it added to the statement object ?
From a performance point of view, both are comparable ? Are they work with the same technique ? Internally, at Database side both will generate same number of queries ?
Somebody please make me understand the difference.
entitymanager will sync the data available in persistence context with Database in a single DB network call
No, not at all. That isn't possible. A flush could possibly delete from several tables, insert in several tables, and update several tables. That can't be done in a single network call.
A flush can use batch statements to execute multiple similar inserts or updates though.
we have to convert an Ooracle database to PostgreSQL. Our database is using triggers and CQN (Continous Query Notification).
Triggers should be save. But we need a functionality in PostgreSQL which mimics CQN.
We use CQN to call a PL/SQL procedure after a commit of a table. In CQN you can define a query, which will be called after a commit. When this query returns a result, then the PL/SQL procedure will be called.
Is there a way to call a procedure in PostgreSQL, when the content of a defined table changed in a transaction?
Sounds like this feature from postgres would look like CQN, although it's definitely not calling SPs(and the transactional MVCC model of postgres means it'd be potentially dangerous to do so)
postgresql listen
I have a Sybase SQL Anywhere 11.0.1 database that I am using to sync with an Oracle Consolidated Database.
I know that the SQL Anywhere database keeps track of all of the changes that are made to it so that it knows what to synchronize with the consolidated database. My question is whether or not there is a SQL command that will tell you if the database has changes to sync.
I have a mobile application and I want to show a little flag to the user anytime they have made changes to the handheld that need to be synced. I could just create another table to track that stuff myself but I would much rather just ping the database and ask it if it has changes that need to be synced.
There's nothing automatic to tell you that there is data to synchronize. In addition to Ben's suggestion, another idea would be to query the SYS.SYSSYNC table at the remote database to get an idea of whether there might be changes. The following statement returns a result set that shows a simple status of your last synchronization :
select ss.site_name, sp.publication_name, ss.log_sent,ss.progress
from sys.syssync ss, sys.syspublication sp
where ss.publication_id = sp.publication_id
and ss.publication_id is not null
and ss.site_name is not null
If progress < log_sent, then the status of the last synchronization is unknown. The last upload may or may not have been applied at the consolidated, because the upload was sent, but no response was received from the MobiLink server. In this case, suggesting a synch isn't a bad idea.
If progress = log_sent, then the last synch was successful. Knowing this, you could check the value of db_property('CurrentRedoPos'), which will return the current log offset of the remote database. If this value is significantly higher than the progress value, there have been many operations applied to the database since the last synchronization, so there's a good chance that there is data to synchronize. There are lots of reasons why even a large difference in progress and db_property('CurrentRedoPos') could result in no actual data needing synchronization.
The download from the ML Server is applied by dbmlsync after the progress value at the remote is updated by dbmlsync when the upload is confirmed by the ML Server. Operations applied in the download by dbmlsync are not synchronized back to the ML Server, so the entire offset range could just be the last download that was applied. This could be worked around by tracking the current log offset in the sp_hook_dbmlsync_end hook when the exit code value in the #hook_dict table value is zero. This would tell you the log offset of the database after the download was applied, and you could now compare the saved value with the current log offset.
All the operations in the transaction log could be operations on tables that are not synchronized.
All the operations in the transaction log could have been rolled back.
My solution is not ideal. Tracking the changes to synchronized tables yourself is the best solution, but I thought I could offer an alternative that might be OK for your needs, with the advantage that you are not triggering an extra action on every operation performed on a synchronized table.
The mobile database doesn't keep track of when the last sync was, the MobiLink server keeps all of that information in the MobiLink tables of the consolidated database.
Since synchronization only transfers necessary information, you could simply initiate a sync. If there's nothing to sync, then very little data will be used by your application.
As a side note, SQL Anywhere has its own SO clone which is monitored by Sybase engineers. If anyone knows for sure, it'll be them.
As of SQL Anywhere 17, SAP PM maps to a local Sybase database that contains a TTRANSACTION_UPLOAD table, so to determine if a synchronization is necessary we simply query this table to see if it has any records that need to be sync'd to the HANA consolidation database.