One way is when using Isolation Level Serializable.
If you have a parent child relationship, as for example in an accounting database with customers, customer accounts, and individual financial debits and credits into those accounts, then:
you have a database transaction consisting of multiple balancing debit and credit entries into the child table, and an accompanying update of an account balance in the customer table.
At isolation level serializable, in order to prevent what are called phantom reads the DB engine places range locks on all records which the SQL statement has to read, (In this case, the credit and debit table). This ensures that no other transaction can insert new credits or debits into the table while this Tx is calculating the new customer balance. Any attempt to insert a new credit or debit is blocked by the lock.
Meanwhile, the first Tx is blocked as well, since the other insert Tx will have placed a lock on the Customer Table row, since it also needs to update the customer Balance. The locks aer not released until the entire Tx is committed, so both Transactions are blocking each other... Deadlock.