問題のMySQLのクエリのトランザクション

生徒たちは、MySQL + MyBatisのを使用して、バックグラウンドのアプリを作るのを助ける前に、長い時間のためにカードをクエリが送信される問題が発生した、と今で再設定するための時間があります

環境条件

学生のテーブルを仮定します。

USE test;
CREATE TABLE `student` (
  Id int  NOT NULL PRIMARY KEY AUTO_INCREMENT,
  Name varchar(20) NOT NULL,
  Grade int NOT NULL
)

MyBatisのプロジェクトのディレクトリ構造は、おおよそ次のように:

+ --- SRC 
| + ---メイン
| | + --- javaの
| | | | Test.javaという
| | | | 
| | | + --- POJO 
| | | | Student.java 
| | | | 
| | | \ --- DAO 
| | | IStudentDao.java 
| | | 
| | \ ---リソース
| | | log4j.properties 
| | | MyBatisの-config.xmlの
| | | 
| | \ ---マッパー
| | StudentMapper.xml

Test.java

import dao.IStudentDao;
import pojo.Student;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Test {
    public static void main(String args[]) throws Exception{
        String resource ="mybatis-config.xml";
        InputStream is = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        IStudentDao studentDAO = sqlSession.getMapper(IStudentDao.class);        
        Student currentStudent;
        
        currentStudent = studentDAO.getStudentById(1);        
        System.out.println(currentStudent);
        
        Thread.sleep(1000 * 30);
        
        currentStudent = studentDAO.getStudentById(1);        
        System.out.println(currentStudent);
    }
}

Student.java

package pojo;

public class Student {
    private int id;
    private String name;
    private int grade;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGrade() {
        return this.grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    @Override
    public String toString(){
        return
                "id = " + id  + "\t" + "name = " + name  + "\t" + "grade = " + grade  + "\t";
    }
}

IStudentDao

package dao;

import org.apache.ibatis.annotations.Param;
import pojo.Student;


public interface IStudentDao {  
    public Student getStudentById(@Param("studentId") int studentId);
}

MyBatisの-config.xmlの

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8&amp;allowMultiQueries=true"/>
        <property name="username" value="root"/>
        <property name="password" value="nihaonihao123123"/>
    </properties>
    
    <environments default="test">
        <environment id="test">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>
</configuration>

StudentMapper.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IStudentDao">
    <select id="getStudentById" resultType="pojo.Student">
        SELECT id AS id, name AS name, grade AS grade
        FROM student
        WHERE id = #{studentId} ;
    </select>
</mapper>

問題のリプレイ

最初のクエリの後、メインスレッドは、「ジョン・ドウ123」、そのままメインスレッドとデータ回復にMySQLのワークベンチ、「ジョン・ドウ」で元のデータを変更した後、30秒間停止します。

私はその後、それがキャッシュの問題だと思ったにMyBatisの-config.xmlでキャッシュを無効にする:設定]タブでは、プロパティは、ラベルの後に追加しました

<settings>
    <setting name="localCacheScope" value="STATEMENT"/>
</settings>

問題は、まだ(時間の変化に注意し、実際に更新されたクエリデータは変更されません)され

16:03:43    UPDATE test.student SET name = '张三123' WHERE id = 1 1 row(s) affected Rows matched: 1  Changed: 1  Warnings: 0  0.062 sec

MyBatisのクエリ結果 - エラー

オープンMySQLのクエリログには、違いを比較します

mysql> set GOLBAL general_log=on;
mysql> show variables like %general%;

MyBatisのトランザクションをコミット - コミットされていません

MySQLのワークベンチは、実際にコミット

注意:自動コミットで私たちのMyBatisのが0に設定されているでは、自動コミットでのMySQLのワークベンチが1に設定されています

この場合には、再度、データベースデータを復元Test.javaが手動で追加提出

currentStudent = studentDAO.getStudentById(1);    
sqlSession.commit();    
System.out.println(currentStudent);

それでも無効!

問題は自動的に提出し、アイデアを存在し、問題がないことを思い出してください。だから、クエリは、文書をMyBatisの。

MyBatisのトランザクションAPIをコミット

あなたは真の引数を提出する義務を追加する必要があります

currentStudent = studentDAO.getStudentById(1);    
sqlSession.commit(true);    
System.out.println(currentStudent);

正しい結果を追加した後\ :: D

MyBatisの正しいクエリ結果

概要

MySQLでは、クエリが提出されない場合、結果はクエリごとに同じである、トランザクションです。しかし、お薦めや自動コミットをオフ(自動コミット= 0が、MySQLまたは自動的にトランザクションをオープンしますが、ない提出)ので、一貫性を確保することができます複数のテーブルにデータを書き込む際に、CRUD操作のため(に単一のクライアント)は、再度シミュレーションを進めると同等、提出し、正しい確認した後にデータを実行することができます。

おすすめ

転載: www.cnblogs.com/battor/p/mybatis_autocommit_problem.html