新年あけましておめでとうございます。旧年は大変お世話になりました。今年も【都内で働くSEの技術的なひとりごと】のご購読よろしくお願いいたします。今年もダイヤモンド修行頑張りますww
Amazonギフト券(グリーティングカードタイプ ) - 10,000円 (お年玉)
- 出版社/メーカー: Amazonギフト券
- 発売日: 2013/01/01
- メディア: Paper Gift Certificate
- この商品を含むブログを見る
新年あけましておめでとうございます。旧年は大変お世話になりました。今年も【都内で働くSEの技術的なひとりごと】のご購読よろしくお願いいたします。今年もダイヤモンド修行頑張りますww
Amazonギフト券(グリーティングカードタイプ ) - 10,000円 (お年玉)
今年は去年と比較すると、投稿数は激減しました。
去年は、120。今年は36。
今年は特に新しいことにも取り組まず、仕事に忙殺されていた感じです。そういう今も仕事の合間に書いてます。来年はもう少しテクニカルなことに取り組まないとなぁと思ってます。あと、オープンソース。
来年もどうぞよろしくお願いいたします。それでは、よいお年をお迎えください♪
過去に C# からデッドロックを例外処理でキャッチするサンプルを作成しました。
ryuchan.hatenablog.com
このサンプルソースに、p_getapplock と sp_releaseapplock を適用し、デッドロックを回避します。まず、それぞれのストアドをコールするロジックを作りましょう。
public int GetAppLock(SqlConnection connection, SqlTransaction transaction) { var command = new SqlCommand("sp_getapplock", connection, transaction); command.CommandType = CommandType.StoredProcedure; command.CommandTimeout = 60000; command.Parameters.AddWithValue("Resource", "lock_resource_id"); command.Parameters.AddWithValue("LockMode", "Exclusive"); command.Parameters.AddWithValue("LockOwner", "Transaction"); command.Parameters.AddWithValue("LockTimeout", 60000); var retCode = command.Parameters.Add("ReturnValue", SqlDbType.Int); retCode.Direction = ParameterDirection.ReturnValue; command.ExecuteNonQuery(); return (int)retCode.Value; } public int ReleaseAppLock(SqlConnection connection, SqlTransaction transaction) { var command = new SqlCommand("sp_releaseapplock", connection, transaction); command.CommandType = CommandType.StoredProcedure; command.CommandTimeout = 60000; command.Parameters.AddWithValue("Resource", "lock_resource_id"); var retCode = command.Parameters.Add("ReturnValue", SqlDbType.Int); retCode.Direction = ParameterDirection.ReturnValue; command.ExecuteNonQuery(); return (int)retCode.Value; }
下記のように組み込みます。
using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var command = connection.CreateCommand(); while (0 == 0) { try { var transaction = connection.BeginTransaction("query1"); if (GetAppLock(connection, transaction) >= 0) { command.Connection = connection; command.Transaction = transaction; command.CommandText = @"UPDATE Production.Product SET Name = N'Bearing Ball' WHERE ProductID = 2;"; command.ExecuteNonQuery(); command.CommandText = @"UPDATE Production.Product SET Name = N'Adjustable Race' WHERE ProductID = 1;"; command.ExecuteNonQuery(); } ReleaseAppLock(connection, transaction); transaction.Commit(); transaction.Dispose(); } catch (SqlException ex) { MessageBox.Show("エラーNo:" + ex.Number.ToString() + " エラーメッセージ:" + ex.Message.ToString()); break; } } command.Dispose(); }
組み込みが完了したら、実行してみましょう。デッドロックが発生しません。dm_tran_locks でアプリケーションロックが発生しているのが判断できます。
LockOwner が Transaction の場合は、明示的に sp_releaseapplock はコールしなくてもいいようですが、個人的に気持ち悪いのでサンプルソースでは呼んでます。さて、今年も残すところあと2日。けど、私は明日から一月中旬までずっとお仕事です....いつになったら、ゆっくり正月を迎えられるようになるんでしょうか....
なぜ、あなたは働くのですか?―仕事を通じて幸せを手に入れる 人生で大切なのは、そんな「天職発想」です
天職は寝て待て?新しい転職・就活・キャリア論? (光文社新書)
今年のダイヤモンド修行は例年になく辛いものでした。今年は関西方面の出張が多かったこともあり FLY ON ポイントが中々貯まらず、挫けそうな時もありましたが(笑)、なんとか達成できました。
インデックスが上手く使われていないことも辛いことですが、デッドロックが発生してしまいデータが...とかなると更にツラいですよね。今回は、sp_getapplock と sp_releaseapplock を使用してデッドロックを回避する方法について説明します。過去にデッドロックについていくつか記事を書いています。今回の記事と合わせて参照してみてください。
ryuchan.hatenablog.com
ryuchan.hatenablog.com
ryuchan.hatenablog.com
ryuchan.hatenablog.com
ryuchan.hatenablog.com
下記のような二つのクエリを同時に実行すると、残念ながらデッドロックが発生してしまいます。(昔の記事で使用したクエリを使用します。よく見るとひどいクエリだ...)
DECLARE @Error_Message NVARCHAR(MAX); DECLARE @Error_Severity INT; DECLARE @Error_State INT; WHILE 0 = 0 BEGIN BEGIN TRY BEGIN TRAN -- ProductID = 2 のデータを更新する。 UPDATE Production.Product SET Name = N'Bearing Ball' WHERE ProductID = 2 -- ProductID = 1 のデータを更新する。 UPDATE Production.Product SET Name = N'Adjustable Race' WHERE ProductID = 1 COMMIT TRAN END TRY -- 例外をキャッチしたら、メッセージを出力して処理を終了する。 BEGIN CATCH SET @Error_Message = ERROR_MESSAGE(); SET @Error_Severity = ERROR_SEVERITY(); SET @Error_State = ERROR_STATE(); RAISERROR(@Error_Message, @Error_Severity, @Error_State); BREAK; END CATCH END
DECLARE @Error_Message NVARCHAR(MAX); DECLARE @Error_Severity INT; DECLARE @Error_State INT; WHILE 0 = 0 BEGIN BEGIN TRY BEGIN TRAN -- ProductID = 1 のデータを更新する。 UPDATE Production.Product SET Name = N'Adjustable Race' WHERE ProductID = 1 -- ProductID = 2 のデータを更新する。 UPDATE Production.Product SET Name = N'Bearing Ball' WHERE ProductID = 2 COMMIT TRAN END TRY -- 例外をキャッチしたら、メッセージを出力して処理を終了する。 BEGIN CATCH SET @Error_Message = ERROR_MESSAGE(); SET @Error_Severity = ERROR_SEVERITY(); SET @Error_State = ERROR_STATE(); RAISERROR(@Error_Message, @Error_Severity, @Error_State); BREAK; END CATCH END
上記のクエリに、sp_getapplock と sp_releaseapplock の処理を加えてみます。
DECLARE @Error_Message NVARCHAR(MAX); DECLARE @Error_Severity INT; DECLARE @Error_State INT; DECLARE @Return_Code INT; WHILE 0 = 0 BEGIN BEGIN TRY BEGIN TRAN -- アプリケーションロックの獲得 EXEC @Return_Code = sp_getapplock @Resource = 'lock_resource_id', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 60000 IF @Return_Code >= 0 BEGIN -- ProductID = 2 のデータを更新する。 UPDATE Production.Product SET Name = N'Bearing Ball' WHERE ProductID = 2 -- ProductID = 1 のデータを更新する。 UPDATE Production.Product SET Name = N'Adjustable Race' WHERE ProductID = 1 -- アプリケーションロックの解放 EXEC sp_releaseapplock @Resource = 'lock_resource_id' END COMMIT TRAN END TRY -- 例外をキャッチしたら、メッセージを出力して処理を終了する。 BEGIN CATCH -- アプリケーションロックの解放 EXEC sp_releaseapplock @Resource = 'lock_resource_id' ROLLBACK SET @Error_Message = ERROR_MESSAGE(); SET @Error_Severity = ERROR_SEVERITY(); SET @Error_State = ERROR_STATE(); RAISERROR(@Error_Message, @Error_Severity, @Error_State); BREAK; END CATCH END
DECLARE @Error_Message NVARCHAR(MAX); DECLARE @Error_Severity INT; DECLARE @Error_State INT; DECLARE @Return_Code INT; WHILE 0 = 0 BEGIN BEGIN TRY BEGIN TRAN -- アプリケーションロックの獲得 EXEC @Return_Code = sp_getapplock @Resource = 'lock_resource_id', @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 60000 IF @Return_Code >= 0 BEGIN -- ProductID = 1 のデータを更新する。 UPDATE Production.Product SET Name = N'Adjustable Race' WHERE ProductID = 1 -- ProductID = 2 のデータを更新する。 UPDATE Production.Product SET Name = N'Bearing Ball' WHERE ProductID = 2 -- アプリケーションロックの解放 EXEC sp_releaseapplock @Resource = 'lock_resource_id' END COMMIT TRAN END TRY -- 例外をキャッチしたら、メッセージを出力して処理を終了する。 BEGIN CATCH -- アプリケーションロックの解放 EXEC sp_releaseapplock @Resource = 'lock_resource_id' ROLLBACK SET @Error_Message = ERROR_MESSAGE(); SET @Error_Severity = ERROR_SEVERITY(); SET @Error_State = ERROR_STATE(); RAISERROR(@Error_Message, @Error_Severity, @Error_State); BREAK; END CATCH END
SQL Server Management Studio で上記のクエリを実行してみましょう。デッドロックは発生しません。
sys.dm_tran_locks から APPLICATION ロックが獲得されているのを確認できます。
通常デッドロックを回避するにはリソース更新順番などを見直すのがベストです。アプリケーションロックを使用するとそれなりに負荷も上がるので、適用するには注意が必要です。
ryuchan.hatenablog.com
新年会は、お肉!赤身最高。
【東京都内】肉通も太鼓判!絶品肉料理に出会えるお店17選 [食べログまとめ]
「よろにく」さん良さそう....
今年の子供のクリスマスプレゼントは Switch 。なんとか手に入った。
それ以外にも色々と購入。
Nintendo Switch 充電ケーブルMatchdor任天堂延長ケーブルUSB3.1 Type-C 高速データ転送 放熱対策 ニンテンドースイッチ ドック用延長ケーブル【第三世代】
【Nintendo Switch対応】全面保護PCカバー for Nintendo Switch
【Nintendo Switch対応】貼りやすいブルーライトカットフィルム ピタ貼り for Nintendo Switch
Switch をやっていると、結構バッテリーを消耗するようなので、自分が今使っているモバイルバッテリーを子供にあげて、自分用に MacBook Pro も充電できるモバイルバッテリーを購入。Parallels で Windows を使っていると異常にバッテリーを使うので必須ですね。丸一日のカンファレンスに参加しても安心です。
全国飛び回りの毎日です。前回、macOS 版の sqlops を試したので、その他にも macOS で何か試したくなりました。
ryuchan.hatenablog.com
今更感はありますが、Docker を試したいと思います。Docker for Mac をダウンロードし、インストールします。
3.25 GB 以上が推奨のようです。ここではとりあえず 3.5 GB にしておきます。
次に Docker に対応した SQL Server をインストールします。下記のコマンドをターミナルから実行します。( 詳しくはココ。 )
$ docker pull microsoft/mssql-server-linux
イメージインストールに成功したら、下記のコマンドを実行し、Docker イメージの SQL Server を実行します。( 詳しくはココ。 )
$ docker run -e ACCEPT_EULA=Y -e SA_PASSWORD=10n@ideh@t@r@ku -p 1433:1433 -d microsoft/mssql-server-linux
SQL Operations Studio から Docker 上の SQL Server に接続してみましょう。sa で接続しましょう。IP は Docker が動作しているクライアントの IP アドレスを設定します。
下記のクエリを実行してみましょう。
SELECT @@VERSION
Microsoft SQL Server 2017 (RTM-CU1) (KB4038634) - 14.0.3006.16 (X64) Oct 19 2017 02:42:29 Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 16.04.3 LTS)
手軽に SQL Server の環境を準備できますね。複数の環境を素早く作成しなければいけない時に重宝しそうですね。Docker 楽しいなぁ。
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化
年末に向けてダイヤモンド修行は続きます(笑)今年はダイヤモンド少し危うい.....気を抜かずに頑張ります(笑)
Microsoft SQL Operations Studio ( sqlops ) Preview がリリースされました。Windows、macOS および Linux で使用することができます。
blogs.technet.microsoft.com
ダウンロードはこちら。
docs.microsoft.com
折角なので、macOS で試してみます。ダウンロードしたファイルを、
アプリケーションにコピーするだけ。普段使用する OS を Windows から macOS にして実感することの一つにインストールが非常に速くて、楽な点があります。
それ以外には、ライブ変換ですね。この機能のおかげで、記事を書くのが非常に早くなりました。
www.youtube.com
Dock より起動します。
Azure 上に展開している SQL Server にアクセスしてみました。
World Wide Importers のデータベースでさらっと触ってみましょう。インテリセンスも動作しますね。
クエリを実行します。
実行プランも表示することができます。
設定は全て JSON なんですね。
当然だとは思いますが、SSMS の方が機能はまだまだ充実しています。今後に期待ですね。
MacBook にすると逆に周辺機器が増える気がする....