Is there an alternative to isolation level SERIALIZABLE?
Give this a try:

BEGIN;
SELECT * FROM products WHERE exported = 0 INTO OUTFILE "x/y/z" FOR UPDATE;
UPDATE products SET exported = 1 WHERE exported = 0;
COMMIT;


And I don't think it matters what the isolation mode is.

I am not sure of mixing INTO OUTPUT with FOR UPDATE; if it give you trouble, make it two SELECTs.

Note that this does obviate your program with the loop and write.  (And it will probably run faster.)

Another approach may be to ping-pong 2 tables.  One is receiving new rows; the other is being exported.  No need to have the exported flag.  More details:  http://mysql.rjweb.org/doc.php/staging_table (especially the section on flip-flop staging).