Truncate Table Within Transaction - sql

Can the SQL "truncate table" command be used within a transaction? I am creating an app and my table has a ton of records. I want to delete all the records, but if the app fails I was to rollback my transaction. Deleting each record takes a very long time. I'm wondering if I use truncate table, can I still rollback the transaction and get my data back in the event of a failure. I realize that truncate table doesn't write each delete to the transaction log, but I'm wondering if it writes the page deallocation to the log so that rollback works.

In SQL Server, you can rollback a TRUNCATE from a transaction. It does write page deallocation to the log, as you mentioned.

In Oracle, TRUNCATE TABLE is a DDL statement that cannot be used in a transaction (or, more accurately, cannot be rolled back). AFAIK, if there is a transaction in progress when the statement is executed, the transaction is committed and then the TRUNCATE is executed and cannot be undone.
In Informix, the behaviour of TRUNCATE is slightly different; you can use TRUNCATE in a transaction, but the only statements permissible after that are COMMIT and ROLLBACK.
Other DBMS probably have their own idiosyncratic interpretations of the behaviour of TRUNCATE TABLE.

If you read the official documentation of PostgreSQL, It said that The TRUNCATE TABLE statement is transaction-safe.

Related

If the table has more than one FOR INSERT trigger and one of them writes to an audit table and the other does a rollback is the audit rolled back

Let's say a table has a validation trigger that enforces some business logic:
TRG_MYTABLE_INSERT_UPDATE_VALIDATION
FOR INSERT, UPDATE on MYTABLE
and an audit trigger that writes all inserts and updates to another table.
TRG_MYTABLE_INSERT_UPDATE_AUDIT
FOR INSERT, UPDATE on MYTABLE
and there's no guarantee that they will be executed in a particular order, will a rollback in the VALIDATION trigger rollback the write to the audit table?
Are all of the triggers enlisted in the same transaction "behind the scenes"?
To answer the question about triggers and transactions: yes triggers are enlisted in the same explicit, or implicit, transaction as the code that executes the statement which makes the trigger fire is enlisted in.
Furthermore, in SQL Server triggers runs be default under XACT_ABORT ON which means that if an error happens in the trigger, the WHOLE transaction is rolled back immediately.
So the answer to your question is that if an error happens in either of the triggers, the whole transaction is rolled back.
You can however do a SET XACT_ABORT OFF in your transaction code, in which case, a rollback would only impact whatever you do in the trigger. That is UNLESS your calling code starts a transaction, and you explicitly do a ROLLBACK in your trigger.
The above is why you should be very careful with using triggers in the first place.

What does COMMIT do?

please I want to understand the difference between the folowing two statements:
insert into table_name values (,,,,,);
and
insert into table_name values (,,,,,);
commit;
If you insert data without commit you can select data from database and see it. But other users can't.
It's better to look to sql documentation:
Until you commit a transaction:
You can see any changes you have made during the transaction by
querying the modified tables, but other users cannot see the changes.
After you commit the transaction, the changes are visible to other
users' statements that execute after the commit.
You can roll back (undo) any changes made during the transaction with
the ROLLBACK statement (see ROLLBACK.
for example here Oracle Documentation
and some info about transactions
All the DML (insert, update , delete) to be inserted in the database you have to commit them, like approve that you want to add them in the database. If you dont commit DML statment , it will not be enter in the database.
what is commit ?
Docs.oracle cant describe it better
Use the COMMIT statement to end your current transaction and make
permanent all changes performed in the transaction. A transaction is a
sequence of SQL statements that Oracle Database treats as a single
unit. his statement also erases all savepoints in the transaction and
releases transaction locks.

Why does Drop Index require commit?

In my multi-threaded program, one thread drops indexes on a table (this happens first), and other threads insert records in the same table. It so happened that when dropping index is attempted, the table gets locked and the insert transactions become "waiting".
After wasting a lot of time on non-solutions to the problem, I found the real solution is to commit immediately after dropping the index. When commit is issued, the table is unlocked and the insert transactions complete successfully.
My question is, why? I was under the impression that Drop Index is a DDL statement and therefore does not need to be committed. Postgres seems to prove me wrong.
In PostgreSQL, all DDL commands are transactional. So if you start a transaction block, or your driver starts a transaction block for you, or your driver is not in autocommit mode, you need to commit all DDL commands, just like other SQL commands.
Other SQL databases do this differently.
(Nitpicking: Some DDL commands in PostgreSQL cannot be run in a transaction block, only in a transaction by themselves. So you may consider those to be exceptions to the above "all DDL commands" claim. But that's not quite the same thing as your question: Those commands still need to be committed, they just can't be run in a transaction together with other commands.)
I don't know about Postgres, but DDL statements are not always auto-committed.
In Oracle for example they are, but in DB2 they are not (you can do a create table + indexes and then rollback the whole lot). I think SQL Server also needs the commit (unless auto-commit is on).
Basically (depending on the DB flavour) a DDL statement is not always auto-committed.

When do I have to commit?

I heard in SQL I do not have to commit every statement. Perhaps create I don't have to.
So can you answer me which Statements I have to commit?
I read, that I have to commit all transactions, but I don't know what this is and can't find it anywhere.
Thanks for your help.
Per the SQL standard, most statements that require a transaction will automatically open one.
Some database engines, such as SQL Server, will (by default) automatically commit the transaction if the statement completes successfully. See Autocommit Transactions.
Autocommit mode is the default transaction management mode of the SQL Server Database Engine. Every Transact-SQL statement is committed or rolled back when it completes
SQL Server also has an Implicit Conversions mode which will leave the transaction open until it's explicitly commited.
When operating in this second such mode (which is the default, I believe, for Oracle), or if you've explicitly created a transaction, it's up to you as a developer when to commit the transaction. It should be when you've accomplished a "complete" set of operations against the database.
If you BEGIN a transaction then you have to either ROLLBACK or COMMIT
Example:
BEGIN TRAN
--Your code
INSERT INTO
NewTable
SELECT *
FROM TABLE
COMMIT TRAN
If you do not use that, it is committed upon execution. So the follow will either fail or be committed:
INSERT INTO
NewTable
SELECT *
FROM Table
If there is an error (like there is no NewTable in the DB) the execution will raise an error and the transaction will roll back. If there is no error the transaction will be committed.

How to rollback delete command without using transaction

How to rollback delete command without using transaction ? if we can't , then what's the difference between Truncate & delete ?
You cannot rollback in this case, but when you are using the Full Recovery Model, then you can turn your database back to the moment before you issued the delete command.
You cannot ROLLBACK an operation without a transaction. You could probably use implicit transactions, but you still need to call COMMIT or ROLLBACK explicitly. However, for better control, it's better to wrap the statement(s) in a BEGIN TRANSACTION...COMMIT / ROLLBACK block anyway. This way you'll avoid any confusion and the need to use the IMPLICIT_TRANSACTION setting.
You can roll back DELETE or TRUNCATE (and most other operations) if and only if they are part of a transaction that's not yet committed. Alternatively you could restore the deleted/truncated data from a backup.
There are several differences between TRUNCATE and DELETE. Most notably TRUNCATE can only empty a table whereas DELETE deletes just the rows you specify. TRUNCATE deallocates and logs data at the page level instead of row level, which typically makes TRUNCATE a more efficient method than DELETE for deleting the entire content of a table.