P
Prismaā€¢2mo ago
SimplyEmu

Question about interactive transactions

I'm reading the docs about interactive transactions and it mentionts to try to not do network requests inside of them. I am trying to create an entry in a playlist table which has a url to a thumbnail. I was going to name the thumbnail using a trigger so the file name can contain playlist Id. The actual thumbnail image is uploaded to S3 after getting the playlist id to name it. I don't want the entry in the database to be created if the image upload fails. Is there a better way to go about this if interactive transactions doc says this is a bad idea?
2 Replies
RaphaelEtim
RaphaelEtimā€¢2mo ago
Hi @SimplyEmu šŸ‘‹ One way to go about this is to: 1. Perform the S3 upload operation before any database transaction. This ensures that the network request is completed successfully before proceeding with database operations. 2. Use a Transaction to Create the Playlist Entry: Once the image is successfully uploaded, start a transaction to create the playlist entry and update it with the thumbnail URL. for example:
const AWS = require('aws-sdk');
const s3 = new AWS.S3();

async function uploadThumbnailToS3(file, playlistId) {
const params = {
Bucket: 'your-bucket-name',
Key: `thumbnails/${playlistId}.jpg`,
Body: file,
ContentType: 'image/jpeg'
};

return s3.upload(params).promise();
}

async function createPlaylistWithThumbnail(prisma, file) {
try {
// Step 1: Create a new playlist entry to get the playlist ID
const newPlaylist = await prisma.playlist.create({
data: {
// your playlist data
}
});

const playlistId = newPlaylist.id;

// Step 2: Upload the thumbnail to S3
await uploadThumbnailToS3(file, playlistId);

// Step 3: Start the transaction to update the playlist entry with the thumbnail URL
await prisma.$transaction(async (tx) => {
await tx.playlist.update({
where: { id: playlistId },
data: {
thumbnailUrl: `https://your-bucket-name.s3.amazonaws.com/thumbnails/${playlistId}.jpg`
}
});
});

} catch (error) {
// Handle the error
console.error('Failed to upload thumbnail or update playlist:', error);
throw error; // Rethrow the error to ensure the transaction is rolled back
}
}
const AWS = require('aws-sdk');
const s3 = new AWS.S3();

async function uploadThumbnailToS3(file, playlistId) {
const params = {
Bucket: 'your-bucket-name',
Key: `thumbnails/${playlistId}.jpg`,
Body: file,
ContentType: 'image/jpeg'
};

return s3.upload(params).promise();
}

async function createPlaylistWithThumbnail(prisma, file) {
try {
// Step 1: Create a new playlist entry to get the playlist ID
const newPlaylist = await prisma.playlist.create({
data: {
// your playlist data
}
});

const playlistId = newPlaylist.id;

// Step 2: Upload the thumbnail to S3
await uploadThumbnailToS3(file, playlistId);

// Step 3: Start the transaction to update the playlist entry with the thumbnail URL
await prisma.$transaction(async (tx) => {
await tx.playlist.update({
where: { id: playlistId },
data: {
thumbnailUrl: `https://your-bucket-name.s3.amazonaws.com/thumbnails/${playlistId}.jpg`
}
});
});

} catch (error) {
// Handle the error
console.error('Failed to upload thumbnail or update playlist:', error);
throw error; // Rethrow the error to ensure the transaction is rolled back
}
}
SimplyEmu
SimplyEmuOPā€¢2mo ago
I think I just need to come up with a different file naming scheme. Iā€™m trying to prevent creating the playlist if the file upload fails. Probably a horrible way to go about it but it is what it is i guess.
Want results from more Discord servers?
Add your server