Will user be able to read data before transaction complete - mysql

I am using code like
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->trans_complete();
same table is used for other read purpose. I don't want other user to read the records until i have finished writing all records. Will transactions take care of it?

If the storage engine from the table support transactions it does.
If you have MyISAM (or mixed) tables you can use LOCK TABLES instead.
LOCK TABLES
table1 WRITE,
table2 WRITE
You'll have to lock all the tables you want to query within the 'transaction'
After you're done use UNLOCK TABLES

Related

MySQL Insert with lock tables write

The task is to upload a price-list of sorts, so quick question before I implement this.
If I want to INSERT say 1000 rows at a time, for say 100,000 the recommendation is:
http://dev.mysql.com/doc/refman/5.5/en/optimizing-myisam-bulk-data-loading.html
"If you do very many successive inserts, you could do a LOCK TABLES followed by an UNLOCK TABLES once in a while (each 1,000 rows or so) to permit other threads to access table. This would still result in a nice performance gain."
Obviously while I have the "WRITE LOCK" on the table you can still read the table right?
The reason I ask is that:
http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
says:
Only the session that holds the lock can access the table. No other session can access it until the lock is released.
"Can access it"... my gosh, if that is the case them our entire system would freeze up... we simply cant have that... Is this in fact the case, or did they mean "...No other session can write to the table until the lock is released."?
Ultimately what I want to be able to do is INSERT 100,000 simple rows of data without impacting the system. I have used:
INSERT INTO a VALUES (1,0.00),(2,0.00), ... ..., (999,0.00)
But this often results in no rows added for some reason.
If you lock a table with LOCK TABLES ... WRITE no other thread can read/write that table.
The best approach is to use multi-row insert statements
INSERT INTO table (f1,f2,f3....) VALUES
(v1,v2,v3...),
(v1,v2,v3...),
...
You will probably need to split your rows into multiple statements with 1-10K rows each (maybe more depending on your max_packet_size and other settings).
MyISAM locks the table if it inserts into empty space somewhere in the middle of the table. If you only do inserts (no deletions) on that table, you should be OK with multiple threads inserting and selecting.
If the table has frequent deletions/updates you should consider switching to InnoDB.
As for "no rows added for some reason"- there is almost certainly an error somewhere in your statement/code. The statement will either insert the rows or return an error.

Making an INSERT ... SELECT statement atomic

I have two tables: one stores data and the other stores locks to indicate when a user is operating on that data. I'd like to select some number of items from the first table, such that they match several conditions and do not have a corresponding lock in the other table, and then add locks for these items to the second table. Since many users may simultaneously attempt to lock items it will be necessary for this to be done atomically.
I've written the SQL statement below to attempt to do this, but I receive the error Deadlock found when trying to get lock;.
INSERT INTO table2 (id, user, date)
SELECT id, ?, NOW()
FROM table1
LEFT JOIN table2 USING id
WHERE locked IS NULL AND <several conditions on table1>
ORDER BY date 'DESC'
LIMIT 15;
Is there any way to make this an atomic operation without locking the tables? Currently I'm using a transaction and reattempting if it's unsuccessful, but I'm interested in whether this is avoidable. I'm using MySQL version 5.0.95 with InnoDB.
Thanks
EDIT
Having given this some further thought I've realised that whilst locking table1 is unacceptable, I can lock table2. Since I can't actually lock the table in the statement (since I have to lock all tables if I choose to lock one of them) I can instead use GET_LOCK to create a mutex preventing multiple processes calling this code simultaneously. I've not yet had a chance to test this approach, but it feels like it might be a more lightweight solution than transactions.
No. This is what the transactions are all about. They organize a bunch of statements in one atomic operation which either succeeds or fails as a whole.
Here you could find some explanation for optimistic and pesimistic lock which perhaps you could find useful. Here you could find some details about the locking mechanism used in InnoDB (pesimistic locking). Here you could find guidelines on how to implement the optimistic locking in mysql.

Check active transactions in MySQL

Is there a way to check the number of active transactions (on the database, not on the local UniConnection component) at any given time, using MySQL + UniConnection?
I'm trying to avoid deadlocks from extended operations and this way I could make one app wait until there are no ongoing active transactions executing from another app, into the same database.
You could use the MySQL Command, SHOW OPEN TABLES, to determine if there is a lock on a table. The in_use column provides the number of table locks or lock requests for tables.
In which case, you could simply LOCK TABLES and UNLOCK TABLES around queries that are expected to have a long execution time.
You can query the INFORMATION_SCHEMA for transaction related tables, I would refer to the Docs about it at MySQL: Information Schema Tables about Transactions

Lock an entire single table but still allow to access other tables in the same session on MySQL

Is it possible to lock a single table on MySQL for a session and still be able to read and write on other unlocked tables on the same session that locked that table while the table is still locked?
Yes, LOCK TABLES does exactly this.

Can I write into table after calling LOCK TABLES tb1 READ?

Can I call update/insert into table(tb1) after calling: LOCK TABLES tb1 READ?
I've read the MySQL manual which says about read lock:
The session that holds the lock can read the table (but not write it).
I'm looking for a lock which allows me to READ/WRITE a table but allowing others only READ access.
How to do it?
Mine is MyISAM database.
You can't do it in MySQL. The best way is to use WRITE lock but then all other sessions will have to wait for ability to read from table.
You probably want to read these first :
http://dev.mysql.com/doc/refman/5.0/en/locking-issues.html
http://en.wikipedia.org/wiki/Isolation_(database_systems)
Read also about lock escalations.
I had issues with earlier versions(4.x) of mysql where I couldn't update the same
table where I was reading from.