• S2JDBC テーブルを利用した独自仕様のid採番メソッド


    AS400DB2では、通常ではトランザクションが扱えないようです。ただし、ジャーナル処理を設定すれば扱えるようになるみたいです。*1

    で、今回の案件

    • ジャーナルは作成しない
    • IDはテーブルを使って採番

    という方針があり、それと関連してFOR UPDATEについてあれこれ調べたりしてました。

    DB2で「SELECT ... FOR UPDATE」のロックを検証 - 130単位
    S2JDBC DB2DialectでのforUpdate()を調べてみた - 130単位

    さて、Javaには「synchronized」という修飾子があるそうです。これをメソッドの宣言に記述すれば、排他処理が行えるとのこと。

    Java スレッド排他制御 synchronizedメソッド‐ニコニコ動画(ββ)
    http://www.nicovideo.jp/watch/sm2346912
    

    というわけで、S2JDBCのサービスにid採番用のメソッドを書いてみます。

    • 採番用テーブルのカラムはkeyとvalueのみ
    • エンティティを作成してSQL自動生成で記述
    • 各サービスから扱えるようにAbstractServiceに定義
    • 最初の採番時、対象キーのレコードが無くても動作可
    • valueカラムの現在値=次に採番される値

    こんな感じの仕様です。

    public abstract class AbstractService<ENTITY> extends S2AbstractService<ENTITY> {
    
        public synchronized int generateId(String key) {
            int id;
    
            IdGenerator idGen = jdbcManager
                .from(IdGenerator.class)
                .where("key = ?", key)
                .getSingleResult();
    
            if (idGen == null) {
                id = 1;
    
                idGen = new IdGenerator();
                idGen.key = key;
                idGen.value = 2;
                jdbcManager.insert(idGen).execute();
            }
            else {
                id = idGen.value;
    
                idGen.value = id + 1;
                jdbcManager.update(idGen).execute();
            }
            return id;
        }
    }
    

    で、synchronizedが実際に効くのかどうか試してみましたが、いまいちわかりませんでした。

    1. トランザクションは無しに設定
    2. メソッドの採番中にユーザーAのみ分岐されるThread#sleep()を仕込む
    3. ユーザーAにて採番実行
    4. ユーザーBにて採番実行

    こんな手順でやってみたのですが、synchronizedがない状態でも3の時点で止まってくれました。おそらく検証方法がまずいのか、理解が足りないかのどちらかかと思われますが…。考えてもわからないので、ひとまず一区切りとしたいと思います。

  • 相关阅读:
    定位小结
    定位知识点
    css属性书写顺序
    清除浮动及清除浮动的方法
    margin合并和塌陷问题
    css特性-层叠性,继承性,优先级
    css属性简写
    css布局之双飞翼布局
    css布局之圣杯布局
    css布局之等高布局
  • 原文地址:https://www.cnblogs.com/aggavara/p/2708720.html
Copyright © 2020-2023  润新知