MySQL query transaction in question

Prior to help students make a background app, using the MySQL + MyBatis, encountered a problem query is submitted, the card for a long time, and now there is time to re-set at

Environmental conditions

Suppose the student table:

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

Mybatis project directory structure roughly as follows:

+---src
|   +---main
|   |   +---java
|   |   |   |   Test.java
|   |   |   |
|   |   |   +---pojo
|   |   |   |       Student.java
|   |   |   |
|   |   |   \---dao
|   |   |           IStudentDao.java
|   |   |
|   |   \---resources
|   |       |   log4j.properties
|   |       |   mybatis-config.xml
|   |       |
|   |       \---mappers
|   |               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>

Problem Replay

After the first query, the main thread to pause for 30 seconds, then modify the original data in MySQL WorkBench, the "John Doe" into a "John Doe 123", the main thread and data recovery without any change.

I thought it was a cache problem, then disable the cache in mybatis-config.xml in : In the configuration tab, properties added after label

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

The problem is still (Note the change in time, and indeed was updated query data does not change)

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 query results - error

Open mysql query log compare differences

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

mybatis commit the transaction - uncommitted

Mysql WorkBench actually commit

Note: In our MyBatis in autocommit is set to 0, MySQL WorkBench in autocommit is set to 1

In this case again restore the database data, in Test.java submitted manually added

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

Still invalid! ! !

Recall that the problem does exist automatically submitted, ideas and there is no problem. So the query mybatis documents.

MyBatis commit the transaction api

You need to add mandatory to submit argument true

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

After adding correct result \ :: D

MyBatis correct query results

to sum up

In MySQL, the query is a transaction, if not submitted, the result is the same for each query. However, recommendations or turn off auto-commit (autocommit = 0, but MySQL or will automatically open a transaction, but not submitted) , so when writing data to multiple tables can ensure consistency; for CRUD operations (in a single client) can perform data after confirming correct, then submit, equivalent to advance simulation again.

Guess you like

Origin www.cnblogs.com/battor/p/mybatis_autocommit_problem.html