diff --git a/program/serializers.py b/program/serializers.py
index 87b1e0f54ef2e26f212e8c2fe27584c7c34ae649..3938ae963d4c74ba98f4b14181db0dd7063e2864 100644
--- a/program/serializers.py
+++ b/program/serializers.py
@@ -30,7 +30,7 @@ from rest_framework.permissions import exceptions
 from django.conf import settings
 from django.contrib.auth.models import User
 from django.core.exceptions import ObjectDoesNotExist
-from django.db import IntegrityError
+from django.db import IntegrityError, transaction
 from django.db.models import Q
 from django.utils import text, timezone
 from program.models import (
@@ -1522,15 +1522,22 @@ class PlaylistSerializer(serializers.ModelSerializer):
 
         entries = validated_data.pop("entries", [])
 
-        playlist = Playlist.objects.create(created_by=user.username, **validated_data)
+        with transaction.atomic():
+            playlist = Playlist.objects.create(created_by=user.username, **validated_data)
 
-        for entry_data in entries:
-            try:
-                PlaylistEntry.objects.create(playlist=playlist, **entry_data)
-            except IntegrityError:
+            for entry_data in entries:
+                try:
+                    PlaylistEntry.objects.create(playlist=playlist, **entry_data)
+                except IntegrityError:
+                    raise exceptions.ValidationError(
+                        code="playlist-entry-file-id-or-uri",
+                        detail="playlist entries must either have file id or uri.",
+                    )
+
+            if playlist.entries.filter(duration__isnull=True).count() > 1:
                 raise exceptions.ValidationError(
-                    code="playlist-entry-file-id-or-uri",
-                    detail="playlist entries must either have file id or uri.",
+                    code="multiple-null-duration-playlist-entries",
+                    detail="playlist may only have one entry without duration",
                 )
 
         return playlist
@@ -1547,26 +1554,33 @@ class PlaylistSerializer(serializers.ModelSerializer):
                 detail="You are not allowed to update this playlist."
             )
 
-        if "description" in validated_data:
-            instance.description = validated_data.pop("description")
+        with transaction.atomic():
+            if "description" in validated_data:
+                instance.description = validated_data.pop("description")
 
-        if "playout_mode" in validated_data:
-            instance.playout_mode = validated_data.pop("playout_mode")
+            if "playout_mode" in validated_data:
+                instance.playout_mode = validated_data.pop("playout_mode")
 
-        if "entries" in validated_data:
-            if instance.entries.count() > 0:
-                for entry in instance.entries.all():
-                    entry.delete(keep_parents=True)
+            if "entries" in validated_data:
+                if instance.entries.count() > 0:
+                    for entry in instance.entries.all():
+                        entry.delete(keep_parents=True)
 
-            for entry_data in validated_data.get("entries"):
-                try:
-                    PlaylistEntry.objects.create(playlist=instance, **entry_data)
-                except IntegrityError:
+                for entry_data in validated_data.get("entries"):
+                    try:
+                        PlaylistEntry.objects.create(playlist=instance, **entry_data)
+                    except IntegrityError:
+                        raise exceptions.ValidationError(
+                            code="playlist-entry-file-id-or-uri",
+                            detail="playlist entries must either have file id or uri.",
+                        )
+
+                if instance.entries.filter(duration__isnull=True).count() > 1:
                     raise exceptions.ValidationError(
-                        code="playlist-entry-file-id-or-uri",
-                        detail="playlist entries must either have file id or uri.",
+                        code="multiple-null-duration-playlist-entries",
+                        detail="playlist may only have one entry without duration",
                     )
 
-        instance.save()
+            instance.save()
 
         return instance