How to implement row level locking using Hibernate Query Language? - mysql

Background: I am working on a MYSql database where multiple instances reads from the same Account Table . I want to implement row level exclusive lock using Hibernate Query Language to avoid dirty read.
My code is as below.
List<AccountTableBean> currentRequestslist = sessionFactory.getCurrentSession()
.createQuery("from Account where status = :finalStatus")
.setLockMode("MappCurrentRequests", LockMode.PESSIMISTIC_READ)
.setParameter("finalStatus","Active").list();
Currently, I have used Pessimistic_read on the entire table. Is there a way i can apply to lock on individual rows? Any example will be very helpful.
Thank you,
Gendaful

The locking type is implied by the database itself.
If you are using MyISAM storage engine, there is nothing you can do to force row level locking, no matter how hard you try - either in raw SQL or in JDBC. MyISAM simply does not support row level locks.
Simply switch to using InnoDB and you won't even have to call setLockMode in order to get the necessary lock type.
From the manual:
MySQL uses row-level locking for InnoDB tables to support simultaneous
write access by multiple sessions, making them suitable for
multi-user, highly concurrent, and OLTP applications. MySQL uses
table-level locking for MyISAM, MEMORY, and MERGE tables, allowing
only one session to update those tables at a time, making them more
suitable for read-only, read-mostly, or single-user applications.

Related

Multiple queries in mysql to the information schema

I am using MySQL and I would like to know if I make multiple select statements simultaneously in order to get information from the information schema, how are these queries handled? Could this cause some potential database malfunction?
Since your are using the myISAM storage engine and are worrying about concurrent SELECT statements:
READ (SELECT) can happen concurrently as long as there is no WRITE (INSERT, UPDATE, DELETE or ALTER TABLE). Ie. you can have either one writer or several readers.
Otherwise the operations are queued and executed as soon as possible.
There is a special case : concurrent inserts.
Note : if you are wondering about the choice between the two main mySQL storage engines myISAM and InnoDB, InnoDB is usually a good choice, please read this SO question.

mysql innodb lock

I am developing application that will run from multiple comuters. I want to lock mysql tables, so there won't be process concurrency issues, like one process is writing and other process is reading at the same time. Or what is even worse both process simultaneously writing (updating) different values. MySQL provides locks, but documentation says that we should avoid using locks with InnoDB. Read here. Please provide some advices what to do in this situation. Thanks everyone.
InnoDB is a transactional storage engine with full ACID support. One of the properties of InnoDB is that it handles the concurrent updates. How exactly depends on the Isolation level, but generally InnoDB disallow two transactions to modify the same row by locking the row. It does not lock the whole table so other records can be modified by other transactions.
If you set the isolation level to serializable the application will work as there is no concurrency at all, but still will allow some concurrency.
The higher the isolation level, the less concurrency you have, still you have more then if you lock the table.

Can I turn transactions off in MySQL/InnoDB?

I have a Django app where the default "REPEATABLE READ" transaction isolation level in InnoDB is causing different processes to have different views of the data than that current in the database.
e.g. Process 1 has made a change but Process 2 isn't seeing it.
I don't need transactional integrity in the app; can I just turn off transactions altogether so that all processes doing a SELECT see the same data?
Any downside to doing this?
Is this what is meant by "READ UNCOMMITTED"?
Any pointers welcome
Rachel
I'd suggest that you just convert the InnoDB tables to myISAM. If your criteria is speed, you are wasting alot of potential by using a transaction oriented table type (InnoDB) and just disabling transactions. You would gain alot if you just converted the tables to myISAM. It's designed with lack of transactions in mind, while still being able to lock changes (i.e. table locks).
A clean
ALTER TABLE table_name ENGINE = MyISAM;
can do the trick for a single table, dumping, changing type and loading the table does the trick as well.
Autocommit is on by default in InnoDB. Transactions are still used for updates (which is necessary), but they are committed immediately after each statement.
The READ UNCOMMITTED isolation level allows a transaction to read rows which have been written by other transactions but haven't yet been committed. This point is irrelevant however if you're not explicitly using transactions and autocommit is on.
Unfortunately, I'm not too familiar with Django, but from the documentation I see:
How to globally deactivate transaction management
Control freaks can totally disable all transaction management by setting
DISABLE_TRANSACTION_MANAGEMENT to True in the Django settings file.
Hope that helps.

Is MySQL InnoDB is appropriate for this scenario?

My MysQL database contains multiple MyISAM tables, with each table containing millions of rows. There is a heavy insert load on the database, so I cannot issue SELECTs on that live database. Instead, I create a replica of the database for queries and conduct analysis on that.
For the analysis, I need to issue multiple parallel queries. The queries are independent (i.e., the results of the queries are not combined together), but they operate on same tables most of the time. As far as I know, the entire MyISAM table is locked for each query, which means parallel independent queries would be slow. Ideally, I would prefer an engine that supports "NO LOCKING". I am assuming MySQL doesnt have such an engine, so should I use InnoDB? I might be missing lot of things here. Please suggest what is the right path to take here.
Thanks
MyISAM read locks are compatible, so the SELECT queries won't lock each other.
If your analysis queries on the replica database don't write, only read, then it's OK to use MyISAM.
You could stick to MyISAM and use INSERT DELAYED:
When a client uses INSERT DELAYED, it gets an okay from the server at once, and the row is queued to be inserted when the table is not in use by any other thread.
Another major benefit of using INSERT DELAYED is that inserts from many clients are bundled together and written in one block. This is much faster than performing many separate inserts.

A lot of writes,but few reads - what Mysql storage engine to use?

I was wondering if anyone has a suggestion for what kind of storage engine to use. The programs needs to perform a lot of writes to database but very few reads.
[edit] No foreign keys necessary. The data is simple, but it needs to preform the writes very fast.
From jpipes:
MyISAM and Table-Level Locks
Unlike InnoDB, which employs row-level
locking, MyISAM uses a much
coarser-grained locking system to
ensure that data is written to the
data file in a protected manner.
Table-level locking is the only level
of lock for MyISAM, and this has a
couple consequences:
Any connection issuing an UPDATE or DELETE against a MyISAM table will
request an exclusive write lock on the
MyISAM table. If no other locks (read
or write) are currently placed on the
table, the exclusive write lock is
granted and all other connections
issuing requests of any kind (DDL,
SELECT, UPDATE, INSERT, DELETE) must
wait until the thread with the
exclusive write lock updates the
record(s) it needs to and then
releases the write lock.
Since there is only table-level locks, there is no ability (like there
is with InnoDB) to only lock one or a
small set of records, allowing other
threads to SELECT from other parts of
the table data.
The point is, for writing, InnoDB is better as it will lock less of the resource and enable more parallel actions/requests to occur.
"It needs to perform the writes very fast" is a vague requirement. Whatever you do, writes may be delayed by contention in the database. If your application needs to not block when it's writing audit records to the database, you should make the audit writing asynchronous and keep your own queue of audit data on disc or in memory (so you don't block the main worker thread/process)
InnoDB may allow concurrent inserts, but that doesn't mean they won't be blocked by contention for resources or internal locks for things like index pages.
MyISAM allows one inserter and several readers ("Concurrent inserts") under the following circumstances:
The table has no "holes in it"
There are no threads trying to do an UPDATE or DELETE
If you have an append-only table, which you recreate each day (or create a new partition every day if you use 5.1 partitioning), you may get away with this.
MyISAM concurrent inserts are mostly very good, IF you can use them.
When writing audit records, do several at a time if possible - this applies whichever storage engine you use. It is a good idea for the audit process to "batch up" records and do an insert of several at once.
You've not really given us enough information to make a considered suggestion - are you wanting to use foreign keys? Row-level locking? Page-level locking? Transactions?
As a general rule, if you want to use transactions, InnoDB/BerkeleyDB. If you don't, MyISAM.
In my experience, MyISAM is great for fast writes as long as, after insertion, it's read-only. It'll keep happily appending faster than any other option I'm familiar with (including supporting indexes).
But as soon as you start deleting records or updating index keys, and it needs to refill emptied holes (in tables or indexes) the discussion gets a lot more complicated.
For classic log-type or journal-type tables, though, it's very happy.