データベースでトランザクションを実行してテーブルにselectを行い、データが存在しないことを確認した上でinsert処理を行う場合に並列でほぼ同時にトランザクションが走ると、お互いにコミットされていないためselectでの存在チェックをすり抜け、insert処理が複数実行されてしまうケースを改善するためにはトランザクションレベルを上げるか、またはテーブルに対してデータが重複しないようにユニークキーを設定するしかないのでしょうか?アプリケーションレベルでの回避は困難なのでしょうか?

追記
RDBMSを使用し(出来ればMysqlかPostgres)、PKをAUTO_INCREMENTに設定している場合です。
ユニークキーを設定した場合や、テーブルロックを行った場合は重複が防げると理解しているのですが、それ以外の方法で回避する方法はないのか知りたいです。
updateの場合はselect for updateを使用すれば該当の行のみをロックすることができますが、insertの場合は対象の行が存在しないため行レベルでのロックが行えないため、ロックするにしてもテーブルロックしか方法がないのかと思っています。

アプリケーションレベルでのトランザクション内で更新とチェックはよくあることだと思うのですが、それに対して他のアプローチや回避策がないかと思い質問させて頂きました。決してRDBMSの機能を一切使わないわけではありません。