メモ:存在しない行を HOLDLOCK すると、Range でロックする

たまたま試す機会があったのでメモ。

テーブル ヒント (Transact-SQL) - SQL Server | Microsoft Docs
には HOLDLOCK は SERIALIZABLE 相当と書かれていて、
SERIALIZABLE では、

SERIALIZABLE 分離レベルで実行しているトランザクションと同じセマンティクスで、スキャンが実行されます。

となっているので、ドキュメント通りなんだけど試したから書いとく。

例1:
存在しない行に UPDLOCK を掛けても、ロックは取られない。
なので、他のトランザクションで行を追加されてしまう。

ロック掛けるセッション

begin tran

select * from [Table] (UPDLOCK) where Id = 6

f:id:odashinsuke:20190118135407j:plain
追加するセッション

begin tran
insert into [Table] values (6, 'abcabc')
select * from [Table]
rollback

f:id:odashinsuke:20190118135431j:plain
Id = 6 が追加される。

例2:
HOLDLOCK にすると、行を追加されない。

ロック掛けるセッション

begin tran

select * from [Table] (HOLDLOCK) where Id = 6

f:id:odashinsuke:20190118140337j:plain 追加するセッション

begin tran
insert into [Table] values (6, 'abcabc')
select * from [Table]
rollback

f:id:odashinsuke:20190118140401j:plain
ロックが解放されるまで追加できない。

ロック状況 f:id:odashinsuke:20190118140438j:plain

範囲でロックを取っているので、今回の場合は Id = 6 だけではなく、6 以上の値では insert 出来ない。
逆に Id = 0 や -1 は insert 可能。

Id が 1 と 5 のデータしかない場合に、Id = 3 で HOLDLOCK 掛けたら、1 より小さい値や、5 より大きい値はロックの範囲外。
2, 3, 4 はロックの範囲内。
多分こんな認識で大丈夫のはず。

SQL Server 2019 から sparkjava を実行してみた

SQL Server 2019 CTP2 で Java を動かしてみた - お だ のスペース で紹介した external_script で Java を呼べる機能を使って、Spark Framework: An expressive web framework for Kotlin and Java を実行してみました。
meetup app osaka@3 で Spark on SQL Server? という話ししました #meetupapp - お だ のスペース のスライドでも書いてますが、動いてますが外部*1から HTTP アクセス出来ませんでした。
なので、同じメソッド内から OkHttp で GETアクセスして動作確認しています。

Java 久しぶりすぎて、Maven も Gradle も書かれへんかった。。
適当に拾ってきたものをいじって、

  • com.sparkjava.spark-core
  • com.squareup.okhttp3.okhttp

を依存関係に突っ込んでるだけです。
幾つか必要な static フィールドがありますが、 How to call Java from SQL - SQL Server Machine Learning Services - SQL Server | Microsoft Docs を見てください。
実装の中で使わなくても今回のケースでは問題無いです。*2

package pkg;

import static spark.Spark.*;
import java.io.IOException;
import java.time.LocalDateTime;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Hoge {
    public static int[] inputDataCol1 = new int[1];
    public static String[] inputDataCol2 = new String[1];

    //Required: Input null map. Size just needs to be set to "1"
    public static boolean[][] inputNullMap = new boolean[1][1];

    //Required: Output data columns returned back to SQL Server
    public static int[] outputDataCol1;
    public static String[] outputDataCol2;

    //Required: Output null map. Is populated with true or false values 
    //to indicate nulls
    public static boolean[][] outputNullMap;

    //Optional: This is only required if parameters are passed with @params
    // from SQL Server in sp_execute_external_script
    // n is giving us the size of ngram substrings
    public static int param1;

    //Optional: The number of rows we will be returning
    public static int numberOfRows;

    //Required: Number of output columns returned
    public static short numberOfOutputCols;

    public static void runSqlServer() {
        get("/hello", (request, response) -> "<h1>Hello Spark!! on SQL Server?</h1>");
        try { 
            String res = run("http://localhost:4567/hello");
            System.out.println(res);
        } catch (IOException e) {
            System.out.println(e);
        }
    }
    static OkHttpClient client = new OkHttpClient();

    static String run(String url) throws IOException {
        Request request = new Request.Builder()
            .url(url)
            .build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }
}

これで HTTP アクセスが失敗する場合は、spark の設定 と HTTP アクセスの間に Thread.sleep なりなんなりで処理を遅らせてください。
Thread.sleep 入れて、実行中にポートの待ち受けを確認するとこんな感じです。
f:id:odashinsuke:20181217163251j:plain スライドにも書いてますが、Java.exe ではなく、ExtHost.exe として動いています。
ExtHost.exe として、4567 ポートで待ち受けています。
メソッド内の処理が全て終わってしまう*3と、spark のサーバーは落ちてしまいます。
外部からアクセス出来ないし、ずっと動かすには sleep や無限ループ等でメソッドが終わらないようにする必要があります。
※ExtHost にタイムアウトがあるかは未検証なので、無限ループの場合は注意
という訳で、余り実用向けではありませんが遊ぶ分には問題ありません。

sparkjava の実行とは関係無いですが、OkHttp なりなんなりで、外部にHTTPアクセスする事も出来ます。
なので外部のAPIとかを叩いてデータを引っ張ってきて遊ぶことも出来ると思います。

今回ご紹介したものは、「実運用を目指していない」お遊びのものなので、本番でこの構成を使おうとか間違っても辞めてね。。

*1:ローカルからの別プロセスも

*2:普通に使うと Java へのパラメーターや戻り値といった使い方になります

*3:external_script の呼出が終わってしまう

meetup app osaka@3 で Spark on SQL Server? という話ししました #meetupapp

なんか色々トラブった*1けど、無事やりきりました。

ざっくり解説すると、
SQL Server 2019 で Big Data Cluster が出て、Spark ジョブも叩けるよーからの、
SQL Server 2019 で追加された Java language extension in SQL Server 2019 - SQL Server Machine Learning Services - SQL Server | Microsoft DocsSpark Framework: An expressive web framework for Kotlin and Java を動かすっていう話しです。
ExtHost.exe(SQL Server External Host) 上で動くから、on って言える??位のネタ話し。

あとは Java から HttpClient で 外部のAPI 叩けるから、どこからでもデータ取れるよー。*2
みたいな感じ。

スライドはこちら

*1:HDMIで繋がらない + PCのタッチパッドが無効になってマウス効かない

*2:使う場合は Firewall の設定は要確認

12/22(土) meetup app osaka@3 で SQL Server 2019 の話しします

今週土曜12/22 に
meetup app osaka@3 - connpass
SQL Server 2019 の話しします。

といっても 15分程度なのでサラッと話す感じですが、内容は「えっ?」ってなるような物を用意しています。
人を選びそうなネタになっていますが、DB系の勉強会では無いので有りじゃないかな?*1

興味ある人はぜひご参加を~。

*1:カテゴリー の Java は話す内容のヒントです

SQL Server 2019 CTP2 で Java を動かしてみた

SQL Server 2019 から external_script で Java が呼べるようになりました。
Java language extension in SQL Server 2019 | Microsoft Docs
How to call Java from SQL | Microsoft Docs
Java language extension in SQL Server 2019 | Microsoft Docs
Java data types supported in SQL Server 2019 | Microsoft Docs

Windows の場合は、JDK1.10 ってありましたが、OracleJDK 11.0.1 でも OK でした。

環境作るの面倒だったので、Azure の VM で Win の SQL Server 2019 CTP2 入りのやつ使いました。
手順通り進めたらサクッと動く感じです。
ハマりどころは LaunchPad サービスを起動してないとダメとか位?

external_script では、2016 で R、2017 で Python が追加されましたが、
実行方法は、下の Execution architecture の箇所に書いてます。
Python extension in SQL Server Machine Learning Services | Microsoft Docs
R extension in SQL Server | Microsoft Docs

要は SQL Server と別プロセスで動く形です。
Python だと Python.exe が動いたので、Java の場合は Java.exe になるのかなーと動かしてみましたがパッと見は分からず。
C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Binn\ExtHost.exe(SQL External Runtime Host) ってのが動いてる感じでしたが、これ経由で Java 動かしてるのかな?

メモ:Tech Summit 2018 Day2

2日目~

即実践! Azure SQL Database Managed Instance 移行

SQL Server 2008 から Azure SQL DB MI(Managed Instance) への移行ハンズオン
2008 のサポートがそろそろ切れるからなんかな?
イベント全体的に 2008 どうにか使用感があった。
移行方法は

今回は DMS を使ったハンズオン
DMS の前に、DMA (Data Migration Assistant (SQL Server) の概要 | Microsoft Docs) もちょっと触る。

MI での相違点
Azure SQL Database Managed Instance の T-SQL の違い | Microsoft Docs

結局ハンズオンは、DMS から接続出来なくて途中でおわた。。

全部出来なかったけど、DMA 殆ど触ってなかったから面白かった。

インフラ野郎 Azure チーム v18.11 ~Azure 半端ないって~

トール・マカベッチ巨匠

インフラ野郎 Azureチーム v18.11 at Tech Summit 2018

Azure Serial Console は憶えてく必要あり!!
無駄な踏み台サーバー、SSH、RDP を用意しなくても良い。
Azure 仮想マシンのシリアル コンソール | Microsoft Docs

HDD と Standard SSD は性能同じだけど安定性が違う。

クライアントの対応が必要だけど Managed Identity(MI) も良い。
Azure リソースのマネージド ID | Microsoft Docs

Front Door Service のデモ
Azure Front Door Service | Microsoft Azure
DNS ベースではなくて、IP Anycast routing

グローバルで活躍する vue.js エキスパートが語る、サーバーレスとの組み合わせによる次世代の最新 Web アプリ開発のご紹介

Vue 知ってる前提のセッション。
決済回りは、Stripe ってのが良く使われてる?
Stripe.js Reference | Stripe

Vue 絡みのセッションだったので、殆どクライアントサイドのお話し。
クライアント側でのエラーは、Application Insights とかで送るくらいなんかなー?

あと Azure Functions 使ってたけど、Consumption Plan なら ColdStart って気にならない位のもんなんかな?

クラウドネイティブなセキュアアプリケーションの作り方に PCIDSS を添えて

AD19_冨田・近江_TechSummit2018

Azure Security and Compliance Blueprint - PaaS Web Application for PCI DSS | Microsoft Docs

セキュリティセンター でスコアが分かる。
Azure Security Center とは | Microsoft Docs

多段防御:あいつは四天王の中で最弱
Key Vault 大事
Azure Key Vault とは | Microsoft Docs

VNet で分離して、Load Balancer か Gateway 経由でアクセスさせる事でログを取得出来る。
Web App も ASE で VNET 内に。

Log Analytics が良く出てきたけど、Azure Monitor に統合された?
Azure Monitor | Microsoft Azure

データ分析基盤エンジンとしての SQL Server 2019 の実力をご覧あれ!

togetter.com

その他

Expo にあった Chatbot ハンズオンになんとなく Node.js で参加ー。


面白かったからなんか作ってみようかなー。