-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use transactions for asset table upserts #142
Changes from all commits
3d07dde
449a5d3
8ac86f6
6ff42c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,9 +67,12 @@ where | |
let tree_id = cl.id.to_bytes(); | ||
let nonce = cl.index as i64; | ||
|
||
// Start a db transaction. | ||
let multi_txn = txn.begin().await?; | ||
|
||
// Partial update of asset table with just leaf info. | ||
upsert_asset_with_leaf_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
nonce, | ||
tree_id.to_vec(), | ||
|
@@ -82,15 +85,18 @@ where | |
|
||
// Partial update of asset table with just leaf owner and delegate. | ||
upsert_asset_with_owner_and_delegate_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
owner_bytes, | ||
delegate, | ||
seq as i64, | ||
) | ||
.await?; | ||
|
||
upsert_asset_with_seq(txn, id_bytes.to_vec(), seq as i64).await?; | ||
upsert_asset_with_seq(&multi_txn, id_bytes.to_vec(), seq as i64).await?; | ||
|
||
// Close out transaction and relinqish the lock. | ||
multi_txn.commit().await?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to know how to handle errors here. what if the transaction fails? Need to have recovery scenarios in that acse surely? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the way it works with SeaORM, if the the transaction ( The reported error will be the one that caused the early return, which is how it functions today. So I think the only difference will be that the |
||
|
||
id_bytes.to_vec() | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,17 +23,25 @@ where | |
return Ok(()); | ||
} | ||
|
||
// Start a db transaction. | ||
let multi_txn = txn.begin().await?; | ||
|
||
// Partial update of asset table with just leaf. | ||
upsert_asset_with_leaf_info_for_decompression(txn, id_bytes.to_vec()).await?; | ||
upsert_asset_with_leaf_info_for_decompression(&multi_txn, id_bytes.to_vec()).await?; | ||
|
||
upsert_asset_with_compression_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
false, | ||
false, | ||
1, | ||
Some(id_bytes.to_vec()), | ||
true, | ||
) | ||
.await | ||
.await?; | ||
|
||
// Close out transaction and relinqish the lock. | ||
multi_txn.commit().await?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to ensure that we know fully what happens if the TX fails and the reason for the TX failing. Is this a recoverable TX error or not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does my explanation above for how SeaORM transactions are rolled back when the object goes out of scope answer the question? Is there some type of recovery we should aim to do, which is different then the current code that afaik just ignores errors and continues on? |
||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,11 +105,13 @@ where | |
.await?; | ||
|
||
// Upsert into `asset` table. | ||
// Start a db transaction. | ||
let multi_txn = txn.begin().await?; | ||
danenbm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Set base mint info. | ||
let tree_id = bundle.keys.get(3).unwrap().0.to_vec(); | ||
unprotected_upsert_asset_base_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
OwnerType::Single, | ||
false, | ||
|
@@ -124,7 +126,7 @@ where | |
|
||
// Partial update of asset table with just compression info elements. | ||
upsert_asset_with_compression_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
true, | ||
false, | ||
|
@@ -136,7 +138,7 @@ where | |
|
||
// Partial update of asset table with just leaf. | ||
upsert_asset_with_leaf_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
nonce as i64, | ||
tree_id, | ||
|
@@ -154,15 +156,21 @@ where | |
Some(delegate.to_bytes().to_vec()) | ||
}; | ||
upsert_asset_with_owner_and_delegate_info( | ||
txn, | ||
&multi_txn, | ||
id_bytes.to_vec(), | ||
owner.to_bytes().to_vec(), | ||
delegate, | ||
seq as i64, | ||
) | ||
.await?; | ||
|
||
upsert_asset_with_seq(txn, id_bytes.to_vec(), seq as i64).await?; | ||
upsert_asset_with_seq(&multi_txn, id_bytes.to_vec(), seq as i64).await?; | ||
|
||
upsert_asset_with_update_metadata_seq(&multi_txn, id_bytes.to_vec(), seq as i64) | ||
.await?; | ||
|
||
// Close out transaction and relinqish the lock. | ||
multi_txn.commit().await?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not include the other updates below? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't want to lock all the different tables at first. Starting with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorporated all these changes into #134 |
||
|
||
// Upsert into `asset_v1_account_attachments` table. | ||
let (edition_attachment_address, _) = find_master_edition_account(&id); | ||
|
@@ -205,8 +213,6 @@ where | |
) | ||
.await?; | ||
|
||
upsert_asset_with_update_metadata_seq(txn, id_bytes.to_vec(), seq as i64).await?; | ||
|
||
if uri.is_empty() { | ||
warn!( | ||
"URI is empty for mint {}. Skipping background task.", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is too late to start the TXN. The TXN should include
asset_should_be_updated
andasset_should_be_updated
should be using SELECT ... FOR UPDATE instead of the SELECT only. This would allow you to lock the rows you are selecting and fail transactions that cause a raise condition.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood, I see how the txn could solve issue with asset_should_be_updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition fixed in #134