How to cleanup INVENTDIM table? - axapta

In AX2009, there exists a process to cleanup unused inventory dimensions not belonging to any transaction.
Is there such a process that I can do in AX4 where INVENTDIM table is now having 20 million+ records.

If there's no such a standard process you can try the following.
write a job to identify all InventDimId (+ReqCovInventDimId,
etc.) fields in all the tables.
write a job or a SQL query to fill in a
temporary table with the InventDimId values from all these fields.
write a job or a SQL query to remove all such records from the InventDim table that don't have InventDimId's in this temporary table.

There is no such standard process.
The courageous might do:
InventDim.skipDeleteActions(true);
InventDim.skipDeleteMethod(true);
delete_from InventDim
notexists join InventTrans
where InventTrans.inventDimId == InventDim.inventDimId;
This will delete any records not referenced by item transactions.
Unfortunately there might exists other references.
You could try a downgrade of the AX 2009 process.

Related

Can a optimistic lock give a deadlock?

Example:
i have a table A (id, version and a field) and a table B (id, version and a field).
i need to make a transaction that edit a record A, and then a record B.
begin transaction
update tableA set field='aaa', version=version+1 where id=1 and version=savedversion
-if recordupdated=0 then rollback
update tableB set field='bbb', version=version+1 where id=1 and version=savedversion
-if recordupdated=0 then rollback
commit
but if i have another thread that need to update the table in reverse order (in a complex environment, there is the possibility that a developer doesn't follow the policies), or needs to update table A (not same record as first transaction), then table B (same record as first transaction), then A (same record as first transaction), can occur a deadlock?
what is the right way to make a transaction in a optimistic lock?
could the solution be using only stored procedures?

How to Insert data in Table1, Table2 and Mapping_Table1_Table2 tables in single query

I am using EF core 2.1. I have Table1. 1 record goes into this. Another table Table2 can have multiple records inserted and mapping_T1_T2 that will keep mapping from Table1 and Table2.
I want to do this in single request to DB through my EF and of course with transactional safely. Either all are added or all rollback in case of any exception.

How to upgrade SQLite deferred Transaction to RESERVED

I'm inserting data to a database where each "batch" must have a new unique id for the batch itself. I could add a batch table and use it's AUTOINCREMENT id, but I don't really need it for anything else, so it seems excessive.
I'm currently doing a SELECT MAX(batchid) + 1 FROM items and then using it for inserts, this is of course prone to race-conditions (2 new batches simultaneously can get conflicting ids)
Using an IMMEDIATE transaction is impractical. Is it possible to force an upgrade of a DEFERRED transaction to EXCLUSIVE before doing the select?
Some ideas;
Can I do some No-op cheap update?
Some explicit instruction to now go exclusive?
INSERT INTO items (batchid, value) VALUES ((SELECT MAX(batchid)+1 FROM items), "monkey"), ((SELECT MAX(batchid)+1 FROM items), "banana"), the idea being that the select is now explicitly part of the update?
It would indeed be possible to put the batch ID lookup into a subquery, but that would be a lot of duplication.
The easiest way is to do something to write to the database, such as PRAGMA user_version = x.

Teradata LOCK ROW FOR ACCESS on insert query into a VOLATILE TABLE

I have a VOLATILE TABLE in teradata that i created with the code below
CREATE VOLATILE TABLE Temp
(
ID VARCHAR(30),
has_cond INT
) ON COMMIT PRESERVE ROWS;
I want to insert records from a select statement that i have created which is a pretty big SQL statement and definitely requires a row lock before proceeding
INSERT INTO Temp
(ID ,has_cond)
SELECT * FROM....
Can anyone tell me how to safely lock the rows so i can insert the records into my VOLATILE TABLE as they are production tables and i don't want to lock out some ETL that might be happening in the background
I don't think you can apply a row lock for an insert unless you put the select in a view.
Or you switch to lock table, but don't forget to include all tables...
But in most production environments there's a database with 1-1-views including lock row access, you can use those (or you might already, check Explain).

does an update statement in oracle hold a lock even if no rows were updated

If I run an update statement in oracle that says '0 rows updated' because it does not match the where clause and i do not commit, does it still hold the lock on any protion of the table? My guess is no, but i cannot prove it.
No row locks are held after an update that didn't update anything (after all, if there is no row, which one should be locked?)
Your transaction will still have some share locks (on the table) but those are only there to prevent other transactions from altering the table. It's basically the same kind of "lock" a select statement acquires on the table.
From the manual:
A row is locked only when modified by a writer.
And further down in the manual:
A row lock, also called a TX lock, is a lock on a single row of table. A transaction acquires a row lock for each row modified
So if no row is changed, there can't be a lock.
It does not hold any lock.
Simple test case
Open two oracle sessions (sqlplus or sqldeveloper or by any other means)
update table1 where clause (session 1)
update table1 where clause (session 2)
Commit from session1 (if there is a table lock then this should hang)
commit from session2 (if there is a table lock then this statement will cause deadlock)
Condition is same with row locking (both sessions deleting same row if exists) as well.
As documented:
The locking characteristics of INSERT, UPDATE, DELETE, and SELECT ... FOR UPDATE statements are as follows:
The transaction that contains a DML statement acquires exclusive row locks on the rows modified by the statement. Other transactions cannot update or delete the locked rows until the locking transaction either commits or rolls back.
The transaction that contains a DML statement does not need to acquire row locks on any rows selected by a subquery or an implicit query, such as a query in a WHERE clause. A subquery or implicit query in a DML statement is guaranteed to be consistent as of the start of the query and does not see the effects of the DML statement it is part of.
A query in a transaction can see the changes made by previous DML statements in the same transaction, but cannot see the changes of other transactions begun after its own transaction.
In addition to the necessary exclusive row locks, a transaction that contains a DML statement acquires at least a row exclusive table lock on the table that contains the affected rows. If the containing transaction already holds a share, share row exclusive, or exclusive table lock for that table, the row exclusive table lock is not acquired. If the containing transaction already holds a row share table lock, Oracle Database automatically converts this lock to a row exclusive table lock.
The table lock is necessary to protect the table from changes while the update is in progress, and if no rows are modified by the update then this is the only lock applied.
If the statement carries out an update on a row that results in no change to that row (eg SET DATE_OF_BIRTH = NULL for a row where date_of_birth is already nullthe row lock is still taken.

Resources