Не, конечно, можно. Если тебе плевать на консистентность.
Смотри: у тебя транзакция, ты делаешь Save() и потом Publish(). А между ними — пропасть, в которую может упасть что угодно: сеть, брокер, твой сервис. 🥣
Transactional Outbox — это когда вместо Publish() ты делаешь ещё один Insert() в таблицу outbox. В той же транзакции. Атомарно.
using var transaction = await _db.BeginTransactionAsync();
_db.Orders.Add(order);
_db.Outbox.Add(new OutboxMessage(order)); // Вместо _kafka.Publish()
await _db.SaveChangesAsync();
await transaction.CommitAsync();
А потом фоновый процесс читает эту таблицу и рассылает.
Это как записка на холодильник: ты не покупаешь бананы прямо сейчас, а пишешь "купить бананы" и точно не забудешь.
Если честно, я использовал этот подход несколько лет и только потом узнал, что это какой-то популярный паттерн.