Is it possible to rollback a CREATE EVENT in MySQL? - mysql

My transaction's sql statements look something like this:
Begin a transaction with START TRANSACTION
Create a record in TEST table
Start a mysql event with CREATE EVENT, using that record's id.
Update a TEST_2 table
Commit the transaction with COMMIT
Of course, if it fails, then I do a ROLLBACK, but after testing, I noticed that the newly created EVENT isn't getting rolled back to nonexistence.
I then found out that CREATE EVENT triggers an implicit COMMIT, in here https://docs.oracle.com/cd/E17952_01/refman-5.1-en/implicit-commit.html
So, is there any way I can automate the event rollback process? Or somehow make it so that the event gets rolled back if the transaction fails?
Thanks.

May triggers do the job? Triggers are designed to execute in response to a specific event that occur in the database.
Oracle Trigger reference

Related

Ensure MySQL transaction fails on COMMIT

I want to test a script what it does when MySQL transaction fails. So I want to simulate transaction failure on COMMIT.
Image the script opens a transaction, makes some queries, and then commits the transaction. I want to implant some extra query to the transaction, to ensure the transaction will fail on COMMIT. So I can test how the script recovers from the transation failure.
I don't want to use explicit ROLLBACK. I want to simulate some real-life case when a commit fails. The exact DB structure is unimportant. It may adapt to the solution.
Edit: I need the transaction to fail on COMMIT, not on some prior query. Therefore answers that rollback prior to COMMIT are not what I want. Such as this one: How to simulate a transaction failure?
My unsuccessful attempts:
Inserting a row with invalid PK or FK fails immediately with insert. Temporarily disabling FK checks with FOREIGN_KEY_CHECKS=0 won't help as they won't be rechecked on COMMIT. If it was psql, defferable constraints would help. But not in mysql.
Opening two parallel transactions and inserting a row with the same PK (or any column with unique constaint) in both transactions locks the later transaction on insert and waits for the former transaction. So the transaction rolls back on insert not on commit.
So I believe you can try the following
Two phase commit : Use two database ( First and second) and make
use of two phase commit. When the commit statement is supposed to be
executed you can shutdown the second db. This way your commit
operation will fail and transaction will rollback.
You executed several inserts and before your commit your database server dies. A transaction may fail if it doesn't receive commit .
Hopefully it helps!

How to make a database updation, creation atomic, and roll back in case of incomplete updation?

I am new to MySQL. I want to perform these operations:
INSERT a record into a table.
CREATE a table if the above INSERT was successful.
How do I make sure that these two things happen as if they are a single DB statement. I mean, I do not want the INSERT to happen and then the CREATE to not happen due to any reason such as power cut, Internet connectivity issues etc.
And if CREATE is incomplete, I want the INSERT command to be rolled back.
Thanks.
You need to package your INSERT and CREATE commands inside a transaction block that starts with START TRANSACTION and either ends with COMMIT if both commands succeed or ends with ROLLBACK if one of the command fails.

Mysql insert row ignoring current transaction

I have a MySQL table implementing a mail queue, and I use it also to send mails which reports unexpected errors in the system. Sometimes these unexcepted errors ocurrs inside a transaction so when I rollback the transacion also I undo the row inserted (the mail which is reporting the unexpected error) in the mail queue table.
My question is how can I force to insert a row in a table in the middle a transaction ignoring the possible transaction rollback?. I mean, If the transactions finally rollsback, not to rollback also the row insertion for the email reporting the error details.
This table can be read by multiple asyncronous process to send the mails in the queue, so in this scenario the rows have to be blocked to send only once the emails so is not possible to use a MyISAM table type and is using Innodb.
Thanks in advance.
If you INSERT should survive a ROLLBACK of the transaction, it is safe to say, that it is not part of the transaction. So what you should do is to simply move it outside the transaction. There are many ways to achieve that:
While in the transaction, instead of running you INSERT, store the
fields in session variables (these will survive a ROLLBACK), after
the transaction run the insert from the session variables
Rethink your schema - this reeks of some deeper-lying problem
Open a second DB connection and run your INSERT on this one, it will not be affected by the transaction on the first connection.
You could create a different connection to the database to insert the errors and it won't be in the same transaction context, so they would be inserted.

mysql transaction in stored procedure (locking/rollback)

does a transaction in a stored procedure do any locking to prevent others from updating tables?
also do i need to explicitly put in rollback logic or will the transaction automatically roll back if an error occurs because it never reaches the commit command.
Does a transaction in a stored procedure do any locking to prevent others from updating tables?
When you perform some DML on an InnoDB table, the rows affected get locked until the end of transaction (doesn't matter is it inside a stored procedure or not).
You can modify the locked rows inside the same transaction that locked it.
To explicitly lock some rows, issue:
SELECT *
FROM table
WHERE condition
FOR UPDATE
Except for commiting or rolling back the transaction, there is no other way to unlock the rows
Do i need to explicitly put in rollback logic or will the transaction automatically roll back if an error occurs because it never reaches the commit command.
You'll need to perform a rollback explicitly.

Transactional updates that are applied to DB regardless of no commit or rollback

I was under the impression that all updates to a SQL server database are first added the T-Log before being applied to the underlying database. In the event of the server crashing, the restore process would rollback any uncommitted transactions. This I also assumed works with transactions, if a commit or rollback is not called the changes will not be made.
So I wanted to see the reaction of SQL server to transactions being cut short. i.e. transactional updates without a commit or rollback. What I found I don’t quite understand. Especially, how SQL server can allow this to happen.
I used the script below to insert rows into a table with a delay to give me enough time to stop the transaction before it reaches the commit or rollback. This I guess would simulate the client application timing out before the transaction completed.
Create Table MyTest (Comment varchar(20))
Go
Create Procedure MyProc
as
Begin Try
Begin Transaction
Insert Into MyTest Select 'My First Entry'
WaitFor Delay '00:00:02'
Insert Into MyTest Select 'My Second Entry'
WaitFor Delay '00:00:02'
Insert Into MyTest Select 'My Third Entry'
Commit Transaction
Return 0 -- success
End Try
Begin Catch
If (##trancount<>0) Rollback Transaction
Declare #err int, #err_msg varchar(max)
Select #err = error_number(), #err_msg = error_message()
Raiserror(#err_msg, 16,1)
Return #err
End Catch
If you run the script, depending on how quickly you stop the procedure, you will see that the first one or two inserts will remain in the table. Could someone explain why this would happen?
Select * From MyTest
I tested this on SQL 2008.
Correct, TXNs are written using "Write Ahead Logging". There are MSDB articles about it and how this interacts with commit/rollback/checkpoints etc
However, a command timout (or what you are doing simply stops code executing) and the TXN is never rolled back and locks released until the connection is closed (or done later separately). This is what SET XACT_ABORT is for
If you begin a transaction and do not commit it or roll it back, you will simply get a hanging transaction that is likely to block other users until something is done with the current transaction. SQL Server will not automatically commit or rollback a transaction on its own, simply because your code didn't do so. The transaction will stay in place and block other users until it's committed or rolled back.
Now, I can quite easily begin a transaction in my T-SQL code, not commit or roll it back, and do a Select statement and see that data that I just inserted or updated as long as the Select statement is using the same connection as my transaction. If I attempt to do a Select using a different transaction, I won't see the inserted or updated data. In fact, the Select statement might not finish at all until the transaction on the other connection is completed.