- ベストアンサー
PHPのODBC接続でトランザクションの競合が発生する問題について
- Web上からPHPへPOSTし、SQLServerへODBC関数を使用して接続しています。
- odbc_autocommitを使用してトランザクションをかけていますが、同時にDBへの登録をすると競合してしまいます。
- PHPのODBC接続で更新中にトランザクション(ロック)をかけることはできないのでしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
「トランザクション」の意味を取り違えていませんか?(COMMITするまで)ROLLBACK可能ではありますが、COMMITしようがROLLBACKしようが無関係なものには何の影響も与えません。レコードをinsertするようなSQL文が待たされたりはしないです。 #でないと大量のデータを処理することが出来ません 手順自体はともかく、同一レコードにアクセスする(更新してcommit前のレコードを他で参照しようとする)ような「最低でもレコードロックしないといけない」SQL文で試しましょうって話です。insertのようなロックする必要がないSQL文でいちいちロック(しかもテーブルロック)するようなRDBMSはちょっと考えられません。 というか >odbc_autocommitを使わず、自分で「BEGIN TRANSACTION」の >SQL分を実行してその後Insert等の処理を行うということでしょうか? 最初の説明では >(4)B端末から「odbc_autocommit」を使用しトランザクション >(5)A端末からTEST_TABLEへInsert 明示的にトランザクションを開始しているように読めましたけど・・ 一般的には ・auto_commitが有効 BEGIN TRANSACTIONがない場合には、SQL文発行ごとにCOMMITするのと同じ(ROLLBACK不可)。 BEGIN TRANSACTIONで明示的にトランザクションを開始したら、COMMIT/ROLLBACKできる。 ・auto_commitが無効 BEGIN TRANSACTIONがない場合でも、SQL文発行でBEGIN TRANSACTIONが自動的に行われる(COMMIT/ROLLBACKできる)。 BEGIN TRANSACTIONで明示的にトランザクションを開始してもいい。 だと思います。
その他の回答 (1)
- agunuz
- ベストアンサー率65% (288/438)
試している処理はロックされていないとマズイような処理なんですかね? SQLServerやそのODBCドライバには詳しくないですが、一般的にinsertあたりはテーブルロックはしません。rollbackしたときに自分が書き込もうとしていたレコードだけ取り消せばいいしauto_increment(synonym)が空き番になるのは「困ることではない」ので。 RDBMSとSQL文によっては更新クエリでもテーブルロックしない(テーブルロックでなくレコードロックする)こともありますから、(同一レコードに対する更新クエリのような)commmit/rollbackが確定するまで待たないといけないようなSQL文で試さないと何とも言えません
補足
複数ユーザーが同時にアクセスする可能性があるため、トランザクションをかけたいと思っています。 例としてInsertを使いましたが、DeleteやUpdateも行われます。 >SQL文で試さないと何とも言えません odbc_autocommitを使わず、自分で「BEGIN TRANSACTION」のSQL分を実行してその後Insert等の処理を行うということでしょうか?
お礼
Updateを実行する際に必要なレコードに対して WITH (UPDLOCK,ROWLOCK)を指定して、処理を待つようにしました。 ありがとうございました