how to monitor who change the data inside the database mysql - java

What I want to achieve is to determine who change the data inside my database table, What I am doing right now is that I created a MySQL trigger that will record the current USER() logged in, but I found a dead end with this since I have multiple users that I want to keep track to, and mysql trigger only allows 1 definer per trigger and I can only have 1 trigger per event which is cannot satisfy my current requirement where I need to keep track of all the users, meaning I need to know which one of them changed anything inside the database. Is there anyway for me to achieve this using mysql trigger? or another by pass option?

Related

How to know if there is a change in the table?

We have a PLM system where users go and create/update objects (i.e. Products, Colorway etc...). This objects eventually gets stored to sqlserver database. The tables do have a column for modifyTimeStamp. The field has updated timestamp when a user updated an object.
We are integrating this tool with some other application. This other application needs to know when someone creates/update objects to our PLM System.
What's the best way to achieve this? Writing some kind of listener which will keep listening and if there is a change in the table, it will notify?
The other approach could be having a trigger. But, then how my code will call that trigger as the triggers are only within the scope of that table?
I think there are many ways to go about to solve this problem. I will try to describe a few.
Creating a scheduler on the listening application. I suggest to implement a scheduler that will run every given interval to fetch the latest data according to the modify time and processing them.
Creating a new API on the listening application and to call it via the creating/updating application.
Using a microservice architecture such as using messaging services between the applications to inform one or another of creation/update events.
I hope it will help you and good luck!
SQL Server has a feature called "Change Tracking". It must first be activated for a database. If it is activated, you can issue special queries that return information about data changes in a specific table.
According to the example in the docs, the query
DECLARE #last_sync_version bigint;
SET #last_sync_version = <value obtained from query>;
SELECT [Emp ID], SSN,
SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION,
SYS_CHANGE_COLUMNS, SYS_CHANGE_CONTEXT
FROM CHANGETABLE (CHANGES Employees, #last_sync_version) AS C;
would return the data changes in the Employees table since #last_sync_version.

Observing #Relation changes in a DataBase

If I something like the following:
#Relation(parentColumn = "id", entityColumn = "fk_id", entity = User.class)
private List<User> users;
This list is a model which gets updated via LiveData.
But I want to be able to update this when I detect changes to the User table. Right now, it only picks up what exists in the DB, but whenever an update happens to the user table, this list does not get updated. Any suggestions?
You have not been very specific in what you are doing or want (which database you use, who is updating the database...).
But I want to be able to update this when I detect changes to the User
table. Right now, this only picks up what exists in the DB but
whenever an update happens to the user table, this list does not get
updated. Any suggestions?
Option 1
If you are doing the update/insert/delete in the same app as the List users, then you can easily update your List in your code.
Option 2
If another app/service is updating the database, I suggest you use a trigger to update your List.
See http://www.coderconsole.com/2015/02/android-sqlite-trigger-demo.html for an example.
Detecting the change in Java is tricky, see Calling a Java method from a sqlite trigger (android) .
Here is an example where you use a ContentObserver to monitor your Sqlite database (the flat file itself) https://gist.github.com/JBirdVegas/3874450
Option 3
If another app/service is updating the database, you can use a BroadcastReceiver to pick up the changes.

Does Firebase Database store the latest data or all the data with timestamp?

I have enabled the Firebase Persistance in my application. If I am setting a value to a child such as
child.setValue("XYZ");
I am not adding value to the parent tree. I am just updating the value of one child. So here, the value will be updated again and again by the user as he uses the application like many times a day. So, my question is, if user do not have inter-net connection for days, will this thing generate bug as Firebase is storing these things in cache. Does all the data get stored offline with mechanism something like commits in git or just the latest value is stored. I am asking this thing because it's kind of cache so if firebase stores data with all the logs and values the child gets then it can make my application buggy and slow as it will carry all the cache all the time.
If you are getting offline and you are updating a single record than, when your getting back online, only your last update will be updated on the server. Let's take an example. You have a product in which you store a timestamp. Every time you make an update, you change that timestamp with the current timestamp. If you are offline and you edit that product several times, when you'll be back online, only the last timpstamp will be added on the server.
But remember, this not happening when you add new data. When you do this, all the new data is added on the server accordingly to time you have added. This happening also when you delete.
Hope it helps.

Possible overwriting to database table

Let's say you have a database table name table1 with columns name and surname. Two different clients open the same view from the java application and get the data for same person at the same time.
1) First client changed the name and pressed save button to update database record.
2) Client2 still sees the old record on the screen and then pressed to save button to change the surname.
It actually overwrite the record by old name. I think to check and get the latest data before updating the database when I click button but I do not like this solution because of making a second query before update.
So how can we solve this problem by using Hibernate and without using Hibarnete. Any idea?
Of course if you do not want that something will be overridden, then you have to check the data before an update. But it will be not always a real query with a good caching strategy. You could also use a timestamp with last update to compare it easier. Another strategy would be to lock the entities when the first user will read them. But that is normally not a good design for web applications or you have to integrate a messaging service, which will all user inform for an update who actually have open that entity. But I think that is not so easy to implement and a more advanced feature.
In short, compare the timestamp of an entity and if already updated, then compare the changes and show them for the user who wanted update that entity.

Keeping search result consistent across multiple transactions

I have to implement a requirement for a Java CRUD application where users want to keep their search results intact even if they do actions which affects the criteria by which the returned rows are matched.
Confused? Ok. Let me give you a familiar example. In Gmail if you do an advanced search on unread emails, you are presented with a list of matching results. Click on an entry and then go back to the search list. What happens is that you have just read that entry but it hasn't disappeard from the original result set. Only that line has changed from bold to normal.
I need to implement the exact same behaviour but the application is designed in such a way that any transaction is persisted first and then the UI requeries the db to keep in sync. The complexity of the application and the size of the database prevents me from doing just a simple in memory caching of the matching rows and making the changes both in db and in memory.
I'm thinking of solving the problem on the database level by creating an intermediate table in the Oracle database holding pointers to matching records and requerying only those records to keep the UI in sync with data. Any Ideas?
In Oracle, if you open a cursor, the results of that cursor are static, regardless if another transaction inserts a row that would appear in your cursor, or updates or deletes a row that does exist in your cursor.
The challenge then is to not close the cursor if you want results consistent from when the cursor was opened.
If the UI maintains a single session on the database, one solution is to use Global Temporary Tables in Oracle. When you execute a search, insert the unique IDs into the GTT, then the UI just queries the GTT.
If the UI doesn't keep the session open, you could do the same thing but with an ordinary table. Then, of course, you'd just have to add some cleanup code to remove old search results from the table.
You can use a flashback query to read data from the past. For example, select * from employee as of timestamp to_timestap('01-MAY-2011 070000', 'DD-MON-YYYY HH24MISS');
Oracle only stores this historical information for a limited period of time. You'll need to look into your retention settings; the UNDO_RETENTION parameter, UNDO tablespace retention gaurantee and proper sizing, and also LOBs have their own retention setting.
Create two connections to the database.
Set the first one to READ ONLY (using SET TRANSACTION READ ONLY) do your searching from that connection but make sure you never end that transaction by issuing a commit or rollback.
As a read only transaction only sees the data as it was at the time the transaction started, the first connection will never see any changes to the database - not even committed ones.
Then you can do your updates in the second connection without affecting the results in the first connection.
If you cannot use two connections, you could implement the updates through stored procedures that use autonomous transactions, then you can keep the read only transaction open in the single connection you have.

Categories