#Question about interactive transactions

3 messages · Page 1 of 1 (latest)

fierce wind
#

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?

austere groveBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

nimble void
#

Hi @fierce wind 👋

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
  }
}