SpringBoot統合Mybatis+事務管理ノート


SpringBoot統合Mybatis+事務管理
事務管理
  • Aは原子性(atomicity)、Bはコンシステンシ(consistency)、トランザクションの実行前後に関わる関連データは一貫性を保つ、Cは隔離性(isolation)、トランザクションが正しく提出されるまで結果は他の事務所に見られない、Dは永続性(durability)
  • サービス層を設計する際には,メソッドに含まれる内容を合理的に抽象化すべきである.
  • そしてメソッドを@Trasactional注記で、デフォルトではExceptionを投げ出す.classが異常な場合、メソッド内のすべてのデータベース操作のロールバックがトリガーされます.もちろん、これは増加、削除、変更を指します.
  • @E n a b l e TransactionManagementで物事を開く
  • @SpringBootApplication
    @EnableTransactionManagement//    
    @MapperScan("com.skysoft.material.dao")// MyBatis Mapper         
    public class MaterialSystemApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MaterialSystemApplication.class, args);
        }
    }
  • 当然、@Transationalメソッドはパラメータ付きであり、具体的なパラメータは以下のように解釈する.
  • ツールバーの
    を選択します.
    説明
    value
    String
    オプションの限定記述子、使用するトランザクションマネージャの指定
    propagation
    enum: Propagation
    オプションのトランザクション伝播動作設定
    isolation
    enum: Isolation
    オプションのトランザクション独立性レベルの設定
    readOnly
    boolean
    読み取り/書き込みまたは読み取り専用トランザクション、デフォルトの読み取り/書き込み
    timeout
    int (in seconds granularity)
    トランザクションタイムアウトの設定
    rollbackFor
    Classオブジェクト配列、Throwableから継承する必要があります
    トランザクションのロールバックを引き起こす例外クラス配列
    rollbackForClassName
    クラス名配列、Throwableから継承する必要があります
    トランザクションのロールバックを引き起こす例外クラス名配列
    noRollbackFor
    Classオブジェクト配列、Throwableから継承する必要があります
    トランザクションがロールバックされない例外クラス配列
    noRollbackForClassName
    クラス名配列、Throwableから継承する必要があります
    トランザクションがロールバックされない例外クラス名配列
    トランザクション独立性レベル
  • 1.Isolation.DEFAULTこれは、最下位のデータストレージを使用するデフォルトの独立性レベルを示すデフォルト値です.その他のすべてのレベルはJDBC独立性レベルに対応します.
  • 2.Isolation.READ_UNCOMMITTEDこの独立性レベルは、あるトランザクションが別のトランザクションの変更を読み取ることができるが、まだコミットされていないデータを示す.このレベルでは、ダーティな読み取りと重複しない読み取りを防止できないため、独立性レベルはあまり使用されません.
  • 3.Isolation.READ_COMMITTED:この独立性レベルは、1つのトランザクションがコミットしたデータのみを読み込むことを示します.このレベルでは、汚れた読み取りを防止できます.これもほとんどの場合の推奨値です.
  • 4.Isolation.REPEATABLE_READ:独立性レベルは、1つのトランザクションがプロセス全体で複数回にわたってクエリを繰り返し実行でき、毎回返されるレコードが同じであることを示します.複数のクエリの間に新しいデータがクエリを満たしている場合でも、これらの新しいレコードは無視されます.このレベルでは、汚れた読み取りと重複しない読み取りを防止できます.
  • 5.Isolation.SERIALIZABLE:すべてのトランザクションが順次実行されるため、トランザクション間の干渉はまったく発生しません.つまり、このレベルでは、汚れた読み取り、重複しない読み取り、幻の読み取りを防止できます.しかし、これはプログラムのパフォーマンスに深刻な影響を及ぼします.通常、このレベルは使用されません.

  • トランザクションのプロパティ
  • 1、PROPAGATION.REQUIRD:現在トランザクションがない場合は新しいトランザクションを作成し、現在トランザクションが存在する場合はそのトランザクションに参加します.この設定は最も一般的な設定です.
  • 2、PROPAGATION.SUPPORTS:現在のトランザクションをサポートし、現在トランザクションが存在する場合はそのトランザクションに参加し、現在トランザクションが存在しない場合は非トランザクションで実行します.
  • 3、PROPAGATION.MANDATORY:現在のトランザクションをサポートし、現在トランザクションが存在する場合はそのトランザクションに参加し、現在トランザクションが存在しない場合は例外を放出します.
  • 4、PROPAGATION.REQUIRES_NEW:現在存在するトランザクションに関係なく新規トランザクションを作成します.
  • 5、PROPAGATION.NOT_SUPPORTED:非トランザクションで実行し、現在トランザクションが存在する場合は、現在のトランザクションを保留します.
  • 6、PROPAGATION.NEVER:非トランザクションで実行され、現在トランザクションが存在する場合は例外が放出されます.
  • 7、PROPAGATION.NESTED:現在トランザクションが存在する場合は、ネストされたトランザクション内で実行します.現在トランザクションがない場合は、PROPAGATION_と実行します.REQUIRD同様の操作.

  • トランザクションの読み取り専用プロパティreadOnly
  • トランザクションの読取り専用属性とは、トランザクションリソースに対して読取り専用または読み書き操作を行うことである.トランザクション・リソースとは、データ・ソース、JMSリソース、カスタム・トランザクション・リソースなど、トランザクションによって管理されるリソースのことです.トランザクション・リソースのみを読み取り専用にすると判断した場合は、トランザクション・フラグを読み取り専用にして、トランザクションのパフォーマンスを向上させることができます.TransactionDefinitionでは、トランザクションが読み取り専用かどうかをbooleanタイプで表します.

  • rollbackForプロパティ
  • デフォルトでは、チェックされていない例外(RuntimeExceptionから継承された例外)またはErrorがトランザクションに投げ出された場合、Springはトランザクションをロールバックします.それ以外の場合、Springはトランザクションをロールバックしません.
  • 他のタイプの例外をトランザクションに投げ出し、Springがトランザクションをロールバックすることを望む場合はrollbackForを指定します.
  • @Transactional(propagation=Propagation.REQUIRED,rollbackFor= MyException.class)

  • 注釈
    @Mapper
    public interface UserMapper {
    
        //     
        @Insert("INSERT INTO user(name,password) VALUES (#{name}, #{password}) ")
        @Options(useGeneratedKeys = true, keyProperty = "id")
        int insert(User user);
    
        @Delete("DELETE FROM user WHERE id = #{id}")
        int delete(@Param("id") Integer id);
    
        @Update("UPDATE user SET name = #{name}, password = #{password} WHERE id = #{id}")
        int update(User user);
    
        @Select("SELECT id, name, password FROM user WHERE id = #{id}")
        @Results(id = "userMap", value = { @Result(column = "id", property = "id", javaType = Integer.class),
                @Result(column = "name", property = "name", javaType = String.class),
                @Result(column = "password", property = "password", javaType = String.class) })
        User findById(Integer id);
    
        @Select("SELECT * FROM user")
        @ResultMap("userMap")
        List<User> fingAll();
    }
  • 複雑クエリー(動的sql):
  • @Mapper
    public interface UserMapper {
    
        //     sql
        @SelectProvider(type = UserMapperProvider.class, method = "findByNameLike")
        List findByNameLike(String name);
    
        //    map
        @SelectProvider(type = UserMapperProvider.class, method = "findByNameAndPassword")
        List findByNameAndPassword(String name, String password);
    
        @InsertProvider(type = UserMapperProvider.class, method = "insert")
        int insertUser(User user);
    
        @DeleteProvider(type = UserMapperProvider.class, method = "delete")
        int deleteUser(Integer id);
    }
  • mappperProvider対象:
  • public class UserMapperProvider {
    
        //     sql
        public String findByName(String name) {
            String sql = "SELECT * FROM user";
            if (StringUtils.isEmpty(name)) {
                return sql;
            }
            sql += " WHERE name LIKE '%" + name + "%'";
            return sql;
        }
    
        //             SQL   
        public String findByNameLike(String name) {
            return new SQL() {
                {
                    SELECT("id, name, password");
                    FROM("user");
                    WHERE("name LIKE '%" + name + "%'");
                }
            }.toString();
        }
    
        public String findByNameAndPassword(Map<String, Object> map) {
    
            String name = (String) map.get("param1");
            String password = (String) map.get("param2");
    
            return new SQL() {
                {
                    SELECT("id, name, password");
                    FROM("user");
                    WHERE("name = " + name);
                    AND();
                    WHERE("password = " + password);
                }
            }.toString();
    
        }
    
        public String update(User user) {
            return new SQL() {
                {
    
                    if (!StringUtils.isEmpty(user.getId())) {
                        UPDATE("user");
                        if (!StringUtils.isEmpty(user.getName())) {
                            SET("name = #{name}");
                        }
                        if (user.getPassword() != null) {
                            SET("password = #{password}");
                        }
                        WHERE("id = #{id}");
                    }
                }
            }.toString();
        }
    
        public String insert(User user) {
            return new SQL() {
                {
                    INSERT_INTO("user");
                    VALUES("name", "#{name}");
                    VALUES("password", "#{password}");
    
                }
            }.toString();
        }
    
        public String delete(Integer id) {
            return new SQL() {
                {
                    DELETE_FROM("user");
                    WHERE("id = #{id}");
                }
            }.toString();
        }
    
    }
    

    XML
    
            
    
    <mapper namespace="cn.sunxyz.mapper.UserMapper">
        
       <insert id="insertUserXml" parameterType="User" keyProperty="id" useGeneratedKeys="true">
           
       insert>
    mapper>