Is it possible to create a Lost Update with MySQL Workbench - mysql

I want to create a Lost Update with MySQL Workbench. Therefore, I have 2 connections to my database and 2 transactions. I also changed the transaction isolation level to read uncommitted but transaction A uses the current data when the update statement starts. It never uses the data from the first select statement and with select ... for update the transaction b is blocked.
Transaction A (starts first):
Start transaction;
SELECT * FROM table;
Select sleep(10); -- <- Transaction B executes in this 10 seconds
UPDATE table SET Number = Number + 10 WHERE FirstName = "Name1";
COMMIT;
Transaction B:
Start transaction;
UPDATE table SET Number = Number - 5 WHERE FirstName = "Name1";
COMMIT;
Is it possible to create this failure with MySQL Workbench. What´s wrong with my code?
Thanks for your help

The update in A work with data after the sleep is executed. Select before does nothing in the transaction.

Related

MySQL SELECT FOR UPDATE is locking whole table

MySQL Version 5.7.16
Process 1:
START TRANSACTION;
SELECT * from statistic_activity WHERE activity_id = 1 FOR UPDATE;
Process 2:
START TRANSACTION;
INSERT INTO `statistic_activity` (`activity_id`) values (2678597);
If Process 1 SELECT statement returns results, Process 2 is not blocked (as you will expect)
But If Process 1 returns empty set (no rows exists with activity_id = 1) then whole table is locked and all INSERTS are blocked until Process 1 transaction ends.
Is this expected behavior ?

Benchmark for a rowlock in mysql

I am trying to benchmark a sql transaction with a select..for update statement which uses an exclusive lock on the row and then insert a row into another table as shown below.
START TRANSACTION;
SELECT CurrentSize
FROM testtable
WHERE id = {id} FOR UPDATE;
-- update current size in testtable
UPDATE testtable
SET currentsize = currentsize + 1
WHERE id = {id} ;
-- insert into a different table
insert into testtable2 values(1,2);
COMMIT;
I am getting 2K tps for the above transaction and I am assuming each transaction takes 0.5ms to complete so giving me 2K tps .
Is it even possible to scale the system beyond this point? If yes is there any implementation that I could try and use.
I am using a 16x.large machine of AWS RDS Aurora MySQL.

How can I rollback a transaction on error in MySQL?

update my_table set limit_id = 2 where id='176846';
start transaction;
update my_table set limit_id = 1 where id='176846';
update my_table set limit_id = 4 where id='176846'; -- <- this one fails
commit;
select limit_id from my_table where id='176846';
I would like to roll this back automatically - I want the script to output 2, not 1. I have no access to the connection policy in use.
reading here:
http://dev.mysql.com/doc/refman/5.5/en/commit.html
By default, MySQL runs with autocommit mode enabled. This means that
as soon as you execute a statement that updates (modifies) a table,
MySQL stores the update on disk to make it permanent. The change
cannot be rolled back.
try something like
SET autocommit = 0;
start transaction;
(...)
commit;
It depends on why a limit_id value of 4 causes an error, but MySql does not always roll back the entire transaction. See: http://dev.mysql.com/doc/refman/5.7/en/innodb-error-handling.html for more information, but in several cases, MySql will only implicitly rollback the last statement, then continue with the transaction.

NHibernate query deadlock in case multiple connection

I have next transaction:
Desc d = new Desc();
d.Descr = "new";
_sess.Transaction.Begin();
_sess.SaveOrUpdate(d);
var desc = _sess.CreateCriteria(typeof(Desc)).List<Desc>();
_sess.Transaction.Commit();
This transaction performs next query:
BEGIN TRANSACTION
INSERT
SELECT
COMMIT TRANSACTION
When I perform this code in two processes I have deadlock, because
1 Process
Perform INSERT and lock Key
2 Process
Perform INSERT and lock key
1 Process wants to perform SELECT and passes in TIMEOUT STATE
2 Process wants to perform SELECT and passes in TIMEOUT STATE
result: deadlock
BD: MS SQL Server 2008 R2
2 questions:
How do me set UPDATE LOCK on All tables what included in transaction
If I use this code:
Desc d = new Desc();
d.Descr = "new";
_sess.Transaction.Begin(IsolationLevel.Serializable);
_sess.SaveOrUpdate(d);
var desc = _sess.CreateCriteria(typeof(Desc)).List();
_sess.Transaction.Commit();
Nothing changes.
What does IsolationLevel.Serializable do ?
UPDATE:
I need to get following:
USE Test
BEGIN TRANSACTION
SELECT TOP 1 Id FROM [Desc] (UPDLOCK)
INSERT INTO [Desc] (Descr) VALUES ('33333')
SELECT * FROM [Desc]
COMMIT TRANSACTION
How do me perform with help NHibernate following:
SELECT TOP 1 Id FROM [Desc] (UPDLOCK)
?
I would change the transaction isolation level to snapshot. This avoids locks when reading data, allows much more concurrency and particularly no deadlocks in read-only transactions.
The reason for the deadlock is following: insert do not conflict with each other. They lock the newly inserted row. The query however is locked out, because it tries to read the newly inserted row from the other transaction. So you get two queries both waiting for the other transaction to complete, which is a deadlock. With isolation level snapshot, the query doesn't care about non committed row at all. Instead of waiting for locks to be released, it only "sees" rows that had been committed. This avoids deadlocks in queries.

SQL Server Select statement with (XLOCK,READPAST)

I ran the following query and my records are locked now I can't read or update or delete. For testing purpose i didn't called commit tran and now these records got stuck. How can I release these locks which are already placed.
BEGIN TRAN
SELECT * from inquiry with (XLOCK,READPAST) where inquiry_id=228563
You should find you lock process id by sys.dm_tran_locks and kill it manually
SELECT * FROM sys.dm_tran_locks WHERE RESOURCE_TYPE = ‘OBJECT’
and then use KILL with id number