codeigniter session save to database keep updating many times - codeigniter

I have a question. I'm using latest version of CI.
I have currently enabled session to use the database, but there is only one problem with how it works since it tends to update the database every time you update your session.
Is there a way to fix that so that session would only update the database once before it destructs?!
I currently have around 9 update requests from one CI session only :) ! so any help would be lovely.
a simple Code example, my proccess is much more complicated than this, but just for demonstration purpose
Controller/auth [include post with true login]
function login(){
$trial=$this->user->attempt($this->input->post('user'),$this->input->post('pass'));
if($trial){
//1st update query
$this->session->set_userdata('user',$trial);
//Start intializing user
//2nd update query
$this->load->model('relations');//constructer will load user friends and save them to $this->session->set_userdata('relations',$rel);
//3rd update query
$this->load->model('settings');//construtor will load user settings and save them to settings
}
}
Above code will create 3 update request all targeted to update field userdata = current session.
my point is there is no need to update db every time we add something to session, its already saved in $_SESSION, so keep it there , and keep manipulating $_SESSION till end,
only updating user_data once at the end of all runtime -destructor- with the end result session is enough to save session to db.
please note that CI loads session from session using select * from ci_session (first request in picture) and then it just keep updating session repeatedly and pointless since it will not select it again during runtime !
so why not just LOAD it once session library is loaded. and save it just before it destruct. thats what im trying to accomplish.
Thanks

I have found a solution for this, get the existing user data from the session by using following code
$userdata = $this->session->all_userdata();
$userdata['fname'] = 'John';
$userdata['lname'] = 'Mulharn';
$userdata['email'] = 'Mulharn#john.com';
$this->session->set_userdata($userdata);
All this happens in 1 transaction instead of 3 database transaction.
Hope that helps.

A session may be updated by passing an array with all of the values, rather than doing them one at a time. Have another look in the Users' Guide

Related

How to prevent two users to edit one row from DB

i am using Spring/Hibernate/ZK. In one tab i get object from DB for editing by user, but second user can open the same tab and the same object for editing . I want to informed second user whit message like "This object is аlready open" and hide buttons for save.Тhus second user can see current data from DB to this object but can`t edint him.Is there a way to check session for this object or another way to do that.
The other answers mostly look at the database, but if all users use the same zk application to access the database, you could keep track of opened objects in the Composer or ViewModel (depending whether you use MVC or MVVM; I'll just call it controller).
Your controller would need a static list of objects that are currently modified. If a user requests to open an object that is not in the list, everything is fine and your controller enables the fields and save button. Otherwise, those are disabled and/or you display a message.
The tricky part is clearing objects from that list. If a user presses the save button, you just remove the object from the list. But what if the user doesn't and just closes the tab or their session just times out? In this case you need a callback, or a mechanism that regularly checks whether the screen is still open.
You could achieve this by adding a zk timer to the tab that pings every now and then and updates the timestamp in your static list (so make it a map). If a new user tries to edit the object, check how old the last timestamp is. If it is old enough (i.e. the previous user saved it or abandoned the screen), allow them to edit it.
Still, you have to think about what to do if a user just keeps the screen open. How long are they allowed to keep the lock on the object? This is an issue in Microsoft Office as well. If multiple users try to open an Excel file from a network location, the first one gets to lock and the others cannot save until that user saves.
You may have additional field which indicates that column is being edited. When first user starts work, the field would be updated. The second user would query object with 'on hold' status and your code would handle this.
Other way - use Hibernate #Version field in your entity. It holds object version which is incremented after every update operation. If second user would save object after first one already saved, it would throw OptimisticLockException which you could handle in your code. More about optimistic and pesimistic locking: Chapter 5. Locking. Related discussions: Hibernate Automatic Versioning and When to use #Version and #Audited in Hibernate?
The best solution is to use Optimistic Concurrency Control with Versioning and when Hibernate throws Concurrency Update issue due to same row is being updated in two transaction then use one of below strategy
First Wins Strategy
Last Wins Strategy
Merge Conflicting Update Strategy
First Wins Strategy is not good solution as it leads to lost update and user will get frustrated that all his work is lost.
By Last Wins Strategy one of user will get error message that you are working on Stale data and start your transaction again . By this way also user can get frustrated due to fact that now again he need to restart operation from beginning but his changes will not lost.
Instead go with Merge conflicting Update Strategy, when Hibernate throws Stale object exception reload screen with new data and user will see updated result and allow him to proceed with latest data. In this user changes will not loss and user will not get error message , just his screen reloads with fresh data and he can decide whether to proceed or not .
You can take example any e-commerce site and you will get one of result of either Last Wins Strategy or Merge Conflicting Update Strategy. Two user can start to by one item but one of user will get message in last screen that item is not stock.

How to perform recaching using memcached?

I am using memcached to cache a table records. My code is as follows
Rails.cache.fetch('custom_profiles') do
#custom_profiles=CustomProfile.where(:status=>"Active")
end
But whenever a new record has been added , its not getting updated.I want to update this variable whenever the table got edited. If you have any idea about this please share with me.
You can delete an item from cache like this
Rails.cache.delete('custom_profiles')
You might want to do this in some callbacks or Observers

mutual exclusion in joomla

I created an extension for joomla using:
$id=$database->insertid();
I just covered that if two users are logged on to the site will fit together perform two records in the database and then this statement will return in both cases the same value.
in php you can solve this problem with the transactions.
In joomla how do I solve this problem?
If you have a table you are working with that extends JTable then make sure that you included the check out functionality that is optionally a part of that. THis must means adding a couple of fields like what is in the content table. This will prevent two people from editing the same row at the same time which creates a race condition in which one of the other will lose their data.
Please note that both php and joomla functions to return the last insert id rely on the mysql implementation, and mysql returns the last id inserted on the currently open connection so concurrency is not an issue
#iacoposk8 Your are right it might possible that in very rear case. Such time try to add current logged in user id in your sql query or any where so that it doesn't make any confict. I hope you get it what i want to say. Thanks

Show all users currently signed in?

I am assuming I cannot do this using sessions but rather the DATABASE. So the user would sign in, it would set their TIMESTAMP and I display that from the database. Then it becomes deleted when the user logs out or their session is terminated. How would the code look for this?
The better question is, is my logic correct? Would this work? Does this make sense?
By default application servers store session data in temporary files on the server.
By storing session data in a database table you are able to create an interface that will show information about the users that are logged in. Apart from that, using this (database) approach is a serious advantage if you need to scale your application by adding more than one server.
One of the most popular ways to implement such a functionality is to create a session table containing your users' session data. This may look like:
create table session (
id number primary key,
data varchar(240),
timestamp date
);
The data column stores all the session data in a serialized form this is deserialized each time a user requests the data.
Serialization and deserialization may have inbuilt support depending on the platform you are using. For example, if you are using PHP, the functions session_encode and session_decode may be found useful.
You can't find out when a user logs out in PHP and the Javascript workarounds are a bit far from a stable solution.
A couple of things you need to do: Create a column in your user table called last_activity and update their last_activity to the current time whenever a user loads a page.
For a list of who's online, query the db for users with last_activity values more recent than 10 or 20 or whatever minutes ago.
To update the last_activity column use:
UPDATE users SET last_activity=CURRENT_TIMESTAMP() WHERE id=2
For a list of users online
SELECT * FROM users where last_activity >= (CURRENT_TIMESTAMP()-(60*20))

CodeIgniter + QuickAuth + One User, only One Session

this may be a easy question, but I really need a light to go on.
I have this huge PHP system in codeigniter, and I'm using the library Quick Auth, and I need let users log on only at one computer/browser at a given time. So if Jake logs on In PC1, then Jakes tries to log on in PC2, PC1 session get invalidated and closed.
I was trying to manually search in the ci_sessions database table to try to eliminate the other user session, but seems like too pain. I want to know if there's one simple solution, I have no problem extending session, but I need more like an advice.
Thanks in advance
You will have to modify either the table indexes or session library code to limit one user to a single session. This can be done by:
Adding a unique index for the username (or ID) and the cookie/session ID
Modifying the library code to INSERT OR REPLACE based on the user/cookie

Resources