Mysql workbench rollback not returning the table to last commit? - mysql-workbench

I'm using the rollback command to go to the previous commit but it doesn't seem to work.
I have tried executing the query multiple time and making sure that I didn't commit again but it doesn't work. I have copied the db from another table. I've executed the command as a block and as a whole but the result remains the same.
INSERT INTO departments_dup
select * from departments;
COMMIT;
UPDATE departments_dup
SET
dept_no = 'd011',
dept_name = 'Quality Control';
select * from departments_dup;
ROLLBACK;
The table should get back to its previous state but it doesn't seem to be working.

Simply use auto-commit before executing ROLLBACK or COMMIT. It worked perfectly for me.
set autocommit = 0;
INSERT INTO departments_dup
select * from departments;
COMMIT;
UPDATE departments_dup
SET
dept_no = 'd011',
dept_name = 'Quality Control';
select * from departments_dup;
ROLLBACK;

If your database tables were created using MyISAM, you will need to backup your database, do a find and replace 'MyISAM' to 'InnoDB' in your backup file and then restore your database.

Related

How to avoid deadlock when delete/update the same record in the Postgres

I have a scenario when I play with Postgres.
We have one table with primary key, and there are two concurrent process, the one can update record, another process can delete record.
Now we are facing deadlock, when two processes play with update/delete the same record in the table.
I google how to avoid deadlock, someone says to use "SELECT FOR UPDATE".
Suppose there are two statements as following
update table_A set name='aaaa' where cid=1;
delete table_A where cid=1;
My question is,
(1) Do I need to add "SELECT FOR UPDATE" to both statements or just one statement in order to avoid deadlock?
(2) Could you give a complete example how to add "SELECT FOR UPDATE" ? I mean, what does it look like after you add "SELECT FOR UPDATE"? I never do it before, I want to learn how to add it.
SELECT ... FOR UPDATE locks the selected rows so that any other transaction can neither perform an update nor a SELECT ... FOR UPDATE on these rows. These transactions must wait until the transaction with the first SELECT ... FOR UPDATE releases the lock on the rows again.
If SELECT ... FOR UPDATE is the first statement in all transactions, no deadlock can occur. Because no transaction can lock other lines, which could be used in the further course of other transactions.
So your two transactions should look like this:
BEGIN;
SELECT * FROM table_A WHERE cid = 1 FOR UPDATE;
-- some other statements
UPDATE table_A SET name = 'aaaa' WHERE cid = 1;
END;
and:
BEGIN;
SELECT * FROM table_A WHERE cid = 1 FOR UPDATE;
-- some other statements
DELETE FROM table_A WHERE cid = 1;
END;

When will select query aquire ExclusiveLock and RowExclusiveLock in PostgreSQL?

According to official documentation, select query only need sharelock, but I found my select query acquired Exclusive lock. How did it happen? Here is my select query:
select gc.id
from group_access_strategy ga
left outer join person_group pg on gp.person_group_id=pg.id
where gp.id=3
what is different from official documentation is that I added left join.
Most likely you ran another command like ALTER TABLE person_group ... (Access Exclusive) or an UPDATE/INSERT/DELETE (Row exclusive) in the same transaction. Locks will persist until a transaction is completed or aborted.
So if you ran:
BEGIN; --BEGIN starts the transaction
UPDATE group_access_strategy SET column = 'some data' where id = 1;
SELECT
gc.id,
FROM
group_access_strategy ga
LEFT OUTER JOIN person_group pg ON (gp.person_group_id = pg.id)
WHERE
pg.id = 3
The UPDATE statement would have created a Row Exclusive Lock that will not be released until you end the transaction by:
Saving all of the changes made since BEGIN:
COMMIT;
OR
nullifying any of the effects of statements since BEGIN with
ROLLBACK;
If you're new to Postgres and typically run your queries in an IDE like PG Admin or DataGrip, the BEGIN / COMMIT ROLLBACK commands are issued behind the scenes for you when you click the corresponding UI buttons.

Is there any way I can resolve this?

SELECT * FROM persons;
COMMIT;
START TRANSACTION;
savepoint SP_UPD;
UPDATE Persons SET Person_name = 'Sachin_Tendulkar'
where id = 1;
savepoint SP_INS;
INSERT INTO persons (Person_name, Nationality) VALUES ('Cillian_Murphy', 'British');
ROLLBACK to SP_INS;
When I ROLLBACK to SP_INS; it's executing the update command but does not executing ROLLBACK to SP_INS;
When I ROLLBACK to SP_UPD; it's gets executed but the table still showing the record I inserted.
Can someone tell me what's wrong here ?
I am using MYSQL btw.

Force a "lock" with Postgres and GO

I am new to Postgres so this may be obvious (or very difficult, I am not sure).
I would like to force a table or row to be "locked" for at least a few seconds at a time. Which will cause a second operation to "wait".
I am using golang with "github.com/lib/pq" to interact with the database.
The reason I need this is because I am working on a project that monitors postgresql. Thanks for any help.
You can also use select ... for update to lock a row or rows for the length of the transaction.
Basically, it's like:
begin;
select * from foo where quatloos = 100 for update;
update foo set feens = feens + 1 where quatloos = 100;
commit;
This will execute an exclusive row-level lock on foo table rows where quatloos = 100. Any other transaction attempting to access those rows will be blocked until commit or rollback has been issued once the select for update has run.
Ideally, these locks should live as short as possible.
See: https://www.postgresql.org/docs/current/static/explicit-locking.html

Rollback DML statement in pgAdmin

In pgAdmin, if I execute an insert query, I don't see any way to either commit or rollback the statement I just ran (I know it auto commits). I'm used to Oracle and SQL developer, where I could run a statement, and then rollback the last statement I ran with a press of a button. How would I achieve the same thing here?
Use transaction in the SQL window:
BEGIN;
DROP TABLE foo;
ROLLBACK; -- or COMMIT;
-- edit --
Another example:
BEGIN;
INSERT INTO foo(bar) VALUES ('baz') RETURNING bar; -- the results will be returned
SELECT * FROM other_table; -- some more result
UPDATE other_table SET var = 'bla' WHERE id = 1 RETURNING *; -- the results will be returned
-- and when you're done with all statements and have seen the results:
ROLLBACK; -- or COMMIT
I also DEARLY prefer the Oracle way of putting everything in a transaction automatically, to help avoid catastrophic manual mistakes.
Having auto-commit enabled by default in an Enterprise product, IMO, is beyond vicious, and nothing but a COMPLETELY, UTTERLY INSANE design-choice :(
Anyways --- working with Postgres, one always needs to remember
BEGIN;
at the start of manual work or sql-scripts.
As a practical habit: then, when you would say: COMMIT;
in Oracle, I use the line
END; BEGIN;
in Postgres which does the same thing, i.e commits the current transaction and immediately starts a new one.
When using JDBC or similar, to create a connection, always use some method, e.g. getPGConnection(), that includes:
...
Connection dbConn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
dbConn.setAutoCommit(false);
...
to make sure every connection has auto-commit disabled.
If you are using pgAdmin4, you can turn the auto commit and/or auto rollback on and off.
Go to the File drop down menu and select Preferences option. In the SQL editor tab -> Options you can see the options to turn auto commit/rollback on and off.
Auto commit/rollback option